poj1985 / poj2631(树的直径)

poj1985 Cow Marathon

树的直径裸题

树的直径的一般求法:

任意一点为起点,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
",ans);
    }return 0;
}
原文地址:https://www.cnblogs.com/kafuuchino/p/9814422.html