当前位置: 代码迷 >> 综合 >> 2018/3/1POJ 1985 Cow Marathon(树的直径)
  详细解决方案

2018/3/1POJ 1985 Cow Marathon(树的直径)

热度:79   发布时间:2023-11-23 07:39:26.0

今天继续饶齐博客

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

具体解法: 首先从树上任意一个点a出发, (BFS)找出到这个点距离最远的点b. 

然后在从b点出发(BFS)找到距离b点最远的点c. 那么bc间的距离就是树的直径.

      


 证明:

       1.    a点在最长路上时, b点一定是最长路的一个端点.

反证:如果b不是端点, 那么最长路的前半段+从a到b的这段必然比原先的最长路更长, 这样就矛盾了.

       2.    a点不在最长路上时, a->b一定与最长路有交点(这是一个结论), 且a->b的后半段一定与最长路重合(如果不重合,那么明显又来了一条比最长路还长的路). 即b一定是最长路的端点.

       程序实现用的是邻接表来表示树结构.

       Head[i]==j 表示与i结点连接的边组成了一条链表, 其中第j条边是这条链的头一个元素, 接着通过j可以找到剩余的(与i连接的)边.

       Edge是用来表示每条边的结构.

       BFS返回从s结点能走到的最远的点的编号



AC代码:

[cpp] view plain  copy
  1. #include<cstdio>  
  2. #include<algorithm>  
  3. #include<cstring>  
  4. #include<queue>  
  5. using namespace std;  
  6. const int maxn=50000+5;  
  7. const int maxm=100000+5;  
  8.   
  9. //有向边  
  10. struct Edge  
  11. {  
  12.     Edge(){}  
  13.     Edge(int to,int cost,int next):to(to),cost(cost),next(next){}  
  14.     int to;   //边尾部  
  15.     int cost; //边距离  
  16.     int next; //指向下条边  
  17. }edges[maxm];  
  18. int cnt=0;    //边总数  
  19. int head[maxn];//头结点  
  20.   
  21. //添加两条有向边  
  22. void AddEdge(int u,int v,int cost)  
  23. {  
  24.     edges[cnt]=Edge(v,cost,head[u]);  
  25.     head[u]=cnt++;  
  26.     edges[cnt]=Edge(u,cost,head[v]);  
  27.     head[v]=cnt++;  
  28. }  
  29.   
  30. //距离  
  31. int dist[maxn];  
  32.   
  33. //BFS返回从s出发能到达的最远点编号  
  34. int BFS(int s)  
  35. {  
  36.     int max_dist=0;  
  37.     int id=s;  
  38.     queue<int> Q;  
  39.     memset(dist,-1,sizeof(dist));  
  40.     dist[s]=0;  
  41.     Q.push(s);  
  42.   
  43.     while(!Q.empty())  
  44.     {  
  45.         int u=Q.front(); Q.pop();  
  46.         if(dist[u]>max_dist)  
  47.             max_dist=dist[id=u];  
  48.         for(int i=head[u]; i!=-1; i=edges[i].next)  
  49.         {  
  50.             Edge &e=edges[i];  
  51.             if(dist[e.to]==-1)  
  52.             {  
  53.                 dist[e.to]=dist[u]+e.cost;  
  54.                 Q.push(e.to);  
  55.             }  
  56.         }  
  57.     }  
  58.     return id;  
  59. }  
  60.   
  61. int main()  
  62. {  
  63.     int n,m;  
  64.     while(scanf("%d%d",&n,&m)==2)  
  65.     {  
  66.         cnt=0;  
  67.         memset(head,-1,sizeof(head));  
  68.         int u,v,cost;  
  69.         char c;  
  70.         for(int i=1;i<=m;i++)  
  71.         {  
  72.             scanf("%d%d%d %c",&u,&v,&cost,&c);  
  73.             AddEdge(u,v,cost);  
  74.         }  
  75.         printf("%d\n",dist[BFS(BFS(u))]);  
  76.     }  
  77.     return 0;  
  78. }  

  相关解决方案