求树的直径【两遍BFS】

两遍BFS。从任意一个点出发,第一遍可以找到直径的一端,从这端出发即可找到另外一端。

证明:从U点出发,到达V【画个图便清晰了】

1.如果U在直径上,则V一定是直径的一个端点。

2.如果U不在直径上。U,V线一定和直径有交点(如果没有交点,从U引一条路到直径交于U'。【反证】)。有交点则V一定是直径另一端。

代码:【举例】

int path(int x){ //从x出发,求直径
    mem(vis,-1);
    while(!Q.empty()) Q.pop();
    Q.push(x);
    vis[x]=0;
    while(!Q.empty()){
        int u=Q.front();    Q.pop();
        int L=G[u].size();
        rep(i,0,L-1){
            int v=G[u][i];
            if(g[u][v]==1 && vis[v]==-1){
                vis[v]=vis[u]+1;
                Q.push(v);
            }
        }
    }
    int ans=-1;
    int vv=-1;
    rep(i,1,n){
        if(vis[i]>ans){
            ans=vis[i];
            vv=i;
        }
    }
    while(!Q.empty()) Q.pop();
    mem(vis,-1);
    Q.push(vv);
    vis[vv]=0;
    while(!Q.empty()){
        int u=Q.front();    Q.pop();
        int L=G[u].size();
        rep(i,0,L-1){
            int v=G[u][i];
            if(g[u][v]==1 && vis[v]==-1){
                vis[v]=vis[u]+1;
                Q.push(v);
            }
        }
    }
    ans=-1;
    rep(i,1,n){
        if(vis[i]>ans){
            ans=vis[i];
        }
    }
    return ans;
}
原文地址:https://www.cnblogs.com/fish7/p/4319288.html