poj 1985 Cow Marathon

题目:传送
题意:
给一棵树,求树的直径。

思路:
观察:从任何一个点出发的最远点一定是一条直径的端点。
证明:
1.点在一条直径上
2.点不在直径上一定和一条直径交叉
所以,我们把这些边存到邻接表中,任选一个起点,进行2次bfs。就可以啦。
上代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
struct edge{
    int from,to,next,w;
}e[100005];
int tot=0;
int first[50005];
int dis[50005];
int n,m;
void add(int from,int tt,int co)
{
    e[tot].to=tt;
    e[tot].w=co;
    e[tot].next=first[from];
    first[from]=tot++;
}
int bfs(int s){
    queue<int> q;
    memset(dis,-1,sizeof(dis));
    dis[s]=0;
    int maxd=0;
    q.push(s);
    int pos=s;
    while(!q.empty())
    {
        int temp=q.front();
        q.pop();
        if(dis[temp]>maxd)
        {
            maxd=dis[temp];
            pos=temp;
        } 
        for(int i=first[temp];i!=-1;i=e[i].next){
            if(dis[e[i].to]== -1)
            {
                dis[e[i].to]=dis[temp]+e[i].w;      
                q.push(e[i].to);
            }
        } 
    }
    //printf("%d\n",pos);
    return pos;
}
int main(){
    int n,m;  
    while(scanf("%d%d",&n,&m)==2)  
    {  
        memset(first,-1,sizeof(first)); 
        int u,v,cost;  
        char c;  
        for(int i=1;i<=m;i++)  
        {  
            scanf("%d%d%d %c",&u,&v,&cost,&c);  
            add(u,v,cost);
            add(v,u,cost);
        }
    printf("%d",dis[bfs(bfs(u))]);
}
}
/*7 6 1 6 13 E 6 3 9 E 3 5 7 S 4 1 3 N 2 4 20 W 4 7 2 S*/

你可能感兴趣的:(poj)