poj1985 / poj2631(树的直径)
树的直径裸题
树的直径的一般求法:
任意一点为起点,dfs/bfs找出与它最远的点$u$
以$u$为起点,dfs/bfs找出与它最远的点$v$
则$d(u,v)$是一条直径
下面给出poj1985的code(poj2631自行修改)
#include<iostream> #include<cstdio> #include<cstring> #define re register using namespace std; int max(int &a,int &b){return a>b?a:b;} #define N 50002 int n,m,k,ans,dis[N]; int cnt,hd[N],nxt[N<<1],ed[N],poi[N<<1],val[N<<1]; void adde(int x,int y,int v){ nxt[ed[x]]=++cnt; hd[x]=hd[x]?hd[x]:cnt; ed[x]=cnt; poi[cnt]=y; val[cnt]=v; } void dfs(int x,int fa){ if(dis[x]>dis[k]) k=x; for(int i=hd[x];i;i=nxt[i]){ int to=poi[i]; if(to==fa) continue; dis[to]=dis[x]+val[i]; dfs(to,x); } } int main(){ char c[3]; int q1,q2,q3; while(~scanf("%d%d",&n,&m)){ memset(hd,0,sizeof(hd)); memset(ed,0,sizeof(ed)); memset(nxt,0,sizeof(nxt)); ans=cnt=k=0; for(re int i=1;i<n;++i){ scanf("%d%d%d%s",&q1,&q2,&q3,c); adde(q1,q2,q3); adde(q2,q1,q3); } dis[1]=1; dfs(1,0); dis[k]=0; dfs(k,0); for(re int i=1;i<=n;++i) ans=max(ans,dis[i]); printf("%d\n",ans); }return 0; }