POJ-2631-Roads in the North-树的直径(最长路)

http://poj.org/problem?id=2631

裸的求树直径, 两次bfs


这种方法是利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点。这样就可以首先任取一个点,bfs求出离其最远的点,在用同样的方法求出离这个叶子节点最远的点,此时两点间的距离就是树的直径。


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const long long N = 1000000000;

struct node
{
    int v,w;
    long long step;
    node(int a=0,int b=0,int c=0)
    {
        v=a;
        w=b;
        step=c;
    }
};
vector <node >sb[10005];
queue<node> q;
int vis[10005];
int main(  )
{
    int i;
    int x,y,w;
    while(scanf("%d %d %d",&x,&y,&w)!=EOF)
    {
        sb[x].push_back(node(y,w));
        sb[y].push_back(node(x,w));

    }
    long long far=0;
    int fari=0;
    q.push(node(1,0,0));
    vis[1]=1;
    while(!q.empty())
    {
        node tp=q.front();
        q.pop();
        for (i=0;i<sb[tp.v].size();i++)
        {
            int w=sb[tp.v][i].w;
            int v=sb[tp.v][i].v;
            if (vis[v]) continue;
            vis[v]=1;
            q.push(node(v,w,tp.step+w));
            if (tp.step+w>far)
            {
                fari=v;
                far=tp.step+w;
            }
        }
    }
//    printf("%d-%d\n",fari,far);
    memset(vis,0,sizeof(vis));
    while(!q.empty()) q.pop();
    q.push(node(fari,0,0));
  vis[fari]=1;
     while(!q.empty())
    {
        node tp=q.front();
        q.pop();
        for (i=0;i<sb[tp.v].size();i++)
        {
            int w=sb[tp.v][i].w;
            int v=sb[tp.v][i].v;
            if (vis[v]) continue;
            vis[v]=1;
            q.push(node(v,tp.w,tp.step+w));
            if (tp.step+w>far)
            {
                fari=v;
                far=tp.step+w;
            }
        }
    }

    printf("%lld\n",far);




    return 0;
}


你可能感兴趣的:(POJ-2631-Roads in the North-树的直径(最长路))