首页 > 代码库 > Farthest Nodes in a Tree (II) LightOJ - 1257

Farthest Nodes in a Tree (II) LightOJ - 1257

技术分享
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
#define MAX_N 300010
using namespace std;
vector<pair<int,int> >G[MAX_N];
int dis1[MAX_N],dis2[MAX_N],vis[MAX_N];
int N;
void bfs(int s,int &t,int dis[])
{
    memset(vis,0,sizeof(vis));
    queue<int>Q;
    Q.push(s); // 把起点入队
    vis[s] = 1;
    dis[s] = 0;
    int maxx = -1;
    while(!Q.empty())
    {
        int e = Q.front();
        Q.pop();
        int sz = G[e].size();
        for(int i = 0; i < sz; i++)
        {
            int v = G[e][i].first;  // 当前到达的点
            int w = G[e][i].second; // 当前边的权值
            if(vis[v]) continue;
            dis[v] = dis[e] + w;
            if(dis[v] > maxx)
            {
                t = v;
                maxx = dis[v];
            }
            vis[v] = 1;
            Q.push(v);
        }
    }
    return ;
}
void Init()
{
    for(int i = 0; i < N; i++)
        G[i].clear();
}
int main()
{
    int T,cas,a,b,c;
    scanf("%d",&T);
    for(cas = 1; cas <= T; cas++)
    {
        scanf("%d",&N);
        Init();
        for(int i = 0; i < N-1; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            G[a].push_back(make_pair(b,c));    // 等价于 g[a][b] = c;
            G[b].push_back(make_pair(a,c));   //  g[b][a] = c;
       }
        int u,v,x;
        bfs(0,u,dis1);
        bfs(u,v,dis1);
        bfs(v,x,dis2);
        printf("Case %d:\n",cas);
        for(int i = 0; i < N; i++)
        {
            printf("%d\n",max(dis1[i],dis2[i]));
        }
    }
    return 0;
}
View Code

 

求无环图(树)上每一个节点可以到达的最远距离

 

(转)证明方法

主要是利用了反证法:
假设 s-t这条路径为树的直径,或者称为树上的最长路
现有结论,从任意一点u出发搜到的最远的点一定是s、t中的一点,
然后再从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜就可以找出树的最长路
证明:
1
设u为s-t路径上的一点,结论显然成立,否则设搜到的最远点为T
则dis(u,T) >dis(u,s) 且 dis(u,T)>dis(u,t)   则最长路不是s-t了,与假设矛盾
2
设u不为s-t路径上的点 首先明确,假如u走到了s-t路径上的一点,那么接下来的路径肯定都在s-t上了,
而且终点为s或t,在1中已经证明过了
所以现在又有两种情况了:
1:u走到了s-t路径上的某点,假设为X,最后肯定走到某个端点,假设是t
   则路径总长度为dis(u,X)+dis(X,t)
2:u走到最远点的路径u-T与s-t无交点,则dis(u-T) > dis(u,X)+dis(X,t);
   显然,如果这个式子成立,
   则dis(u,T)+dis(s,X)+dis(u,X)>dis(s,X)+dis(X,t)=dis(s,t)
   最长路不是s-t矛盾

 

Farthest Nodes in a Tree (II) LightOJ - 1257