//#pragma GCC optimize(3,"Ofast","inline")
//#pragma GCC optimize(2)
#include<iostream>
#include<vector>
#include<cstring>
//#include<stack>
#define int long long
using namespace std;
const int N=200005;
//vector<int> g[N],w[N];
long long head[2*N],nxt[2*N],g[2*N],w[2*N],cnt=0;
inline void add(int u,int v,int ww)
{
++cnt;
g[cnt]=v;
w[cnt]=ww;
nxt[cnt]=head[u];
head[u]=cnt;
}
int n;
inline void getll(long long& n)
{
n=0;
long long k=1;
char c=getchar();
while((c<'0'||c>'9')&&c!='-') c=getchar();
if(c=='-') k=-1,c=getchar();
while('0'<=c&&c<='9') n=n*10+c-'0',c=getchar();
n*=k;
}
/*inline void getint(int& n)
{
n=0;
int k=1;
char c=getchar();
while((c<'0'||c>'9')&&c!='-') c=getchar();
if(c=='-') k=-1,c=getchar();
while('0'<=c&&c<='9') n=n*10+c-'0',c=getchar();
n*=k;
}*/
struct ISTREAM{} _cin;
ISTREAM& operator>>(ISTREAM& istr,long long& n){getll(n);return istr;}
//ISTREAM& operator>>(ISTREAM& istr,int& n){getint(n);return istr;}
namespace DFS
{
int dist[N];
int farest;
int p1,p2,p1i;
//p1==p2: mid is p1
//p1!=p2: mid is a point between p1 and p2,which is on edge g[p1][p1i]
int istk[N],top=0;//stores all of the g[][i]
int Istk[N],Top=0;//maxp
inline void initdist(int p)
{
memset(dist,0x3f,sizeof dist);
dist[p]=0;
farest=p;
p1=p2=p1i=0;
top=Top=0;
}
inline void dfs(int p,int fa)
{
//cout<<"dist["<<p<<"]="<<dist[p];
if(dist[p]>dist[farest])
{
farest=p;
for(int i=1;i<=top;++i) Istk[i]=istk[i];
Top=top;
//cout<<" is the farest";
}
//cout<<endl;
for(int i=head[p];i;i=nxt[i])
if(g[i]!=fa)
{
dist[g[i]]=dist[p]+w[i];
istk[++top]=i;//pushstack
dfs(g[i],p);
--top;//popstack
}
}
inline void getmid(int P1)
{
p1=P1;
for(int i=1;i<=Top;++i)
{
p2=g[Istk[i]];
if(dist[p2]*2<dist[farest])//haven't reach yet
p1=p2;
else if(dist[p2]*2==dist[farest])//a point
{
p1=p2;
return;
}
else
{
p1i=Istk[i];
return;
}
}
}
}
namespace DP
{
int f[N],g[N];
inline bool dfs(int p,int fa,int D)//g=int[] ::g=vector<int>[]
{
//cout<<"dfs("<<p<<","<<fa<<","<<D<<')'<<'\n';
f[p]=0;
g[p]=0;
for(int i=::head[p];i;i=nxt[i])
if(::g[i]!=fa)
if(dfs(::g[i],p,D))
{
f[p]++;
if(f[p]>1) g[p]=0;
else g[p]=1+g[::g[i]];
}
if(DFS::dist[p]==D) f[p]++,g[p]=0;
//cout<<"f["<<p<<"]="<<f[p]<<" g["<<p<<"]="<<g[p]<<'\n';
return f[p];
}
}
signed main()
{
//ios::sync_with_stdio(false);
_cin>>n;
for(int i=1;i<n;++i)
{
int x,y,z;
_cin>>x>>y>>z;
add(x,y,z);
add(y,x,z);
}
DFS::initdist(1);
DFS::dfs(1,0);
int A=DFS::farest;
DFS::initdist(A);
DFS::dfs(A,0);
int B=DFS::farest;
cout<<DFS::dist[B]<<'\n';
//cout<<"A="<<A<<" B="<<B<<endl;
DFS::getmid(A);
int p1=DFS::p1,p2=DFS::p2;
if(p1==p2)
{
int ans=2;
int hdist=DFS::dist[B]/2;
DFS::initdist(p1);
DFS::dfs(p1,0);
for(int i=head[p1];i;i=nxt[i])
if(DP::dfs(g[i],p1,hdist))
{
DP::f[p1]++;
ans+=DP::g[g[i]];
}
if(DP::f[p1]>=3) cout<<'0';
else cout<<ans;
}
else
{
//cout<<"mid is between "<<DFS::p1<<" and "<<DFS::p2<<endl;
int Ap1=DFS::dist[p1];
DFS::initdist(B);
DFS::dfs(B,0);
int Bp2=DFS::dist[p2];
DFS::initdist(p1);
DFS::dfs(p1,0);
DP::dfs(p1,p2,Ap1);
DFS::initdist(p2);
DFS::dfs(p2,0);
DP::dfs(p2,p1,Bp2);
cout<<1+DP::g[p1]+DP::g[p2];
}
return 0;
}
开O2是70分,没过200000的点;不开是40分,100000和200000都过不了,所以我觉得是常数的问题,但是不知道还有什么地方可以优化