CF 120F Spider 树的直径 简单题

一个男孩有n只玩具蜘蛛,每只蜘蛛都是一个树的结构,现在男孩准备把这n只小蜘蛛通过粘贴节点接在一起,形成一只大的蜘蛛。大的蜘蛛也依然是树的结构。输出大的蜘蛛的直径。

 

知识:

树的直径是指树上的最长简单路

求树的直径有个结论:

假设s-t这条路径为树的直径,或者称为树上的最长路。

从任意一点u出发搜到的最远的点一定是s、t中的一点,然后再从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜或者深搜就可以找出树的最长路

证明:反证法。

 

那回到这道题,要使得大蜘蛛的直径最大,就要使连接的小蜘蛛都是用s,t2个点来和其他蜘蛛连接

所以大蜘蛛的直径就是小蜘蛛的直径的和

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 
  5 using namespace std;
  6 
  7 const int maxn=105;
  8 const int inf=0x3f3f3f3f;
  9 
 10 struct Edge
 11 {
 12     int to,next;
 13 };
 14 Edge edge[maxn<<1];
 15 int head[maxn];
 16 int tot;
 17 bool vis[maxn];
 18 struct Point
 19 {
 20     int num,dis;
 21 };
 22 
 23 void init()
 24 {
 25     memset(head,-1,sizeof head);
 26     tot=0;
 27 }
 28 
 29 void addedge(int u,int v)
 30 {
 31     edge[tot].to=v;
 32     edge[tot].next=head[u];
 33     head[u]=tot++;
 34 }
 35 
 36 //返回树的直径
 37 int solve(int m);
 38 //返回结构体,树的节点和节点到u的距离
 39 Point bfs(int u,int m);
 40 
 41 int main()
 42 {
 43     freopen("input.txt","r",stdin);
 44     freopen("output.txt","w",stdout);
 45     int n;
 46     scanf("%d",&n);
 47     int ans=0;
 48     for(int i=1;i<=n;i++)
 49     {
 50         init();
 51         int m;
 52         scanf("%d",&m);
 53         for(int i=1;i<m;i++)
 54         {
 55             int u,v;
 56             scanf("%d %d",&u,&v);
 57             addedge(u,v);
 58             addedge(v,u);
 59         }
 60         ans+=solve(m);
 61     }
 62     printf("%d\n",ans);
 63 
 64     return 0;
 65 }
 66 
 67 int solve(int m)
 68 {
 69     Point cnt=bfs(1,m);
 70     Point ret=bfs(cnt.num,m);
 71     return ret.dis;
 72 }
 73 
 74 Point bfs(int s,int m)
 75 {
 76     memset(vis,false,sizeof vis);
 77     Point start;
 78     start.num=s;
 79     start.dis=0;
 80     vis[s]=true;
 81     queue<Point>que;
 82     while(!que.empty())
 83         que.pop();
 84     que.push(start);
 85     Point ret;
 86     while(!que.empty())
 87     {
 88         Point u=que.front();
 89         que.pop();
 90         if(que.empty())
 91         {
 92             ret.num=u.num;
 93             ret.dis=u.dis;
 94         }
 95         for(int i=head[u.num];~i;i=edge[i].next)
 96         {
 97             int v=edge[i].to;
 98             if(vis[v])
 99                 continue;
100             Point uu;
101             uu.num=v;
102             uu.dis=u.dis+1;
103             vis[v]=true;
104             que.push(uu);
105         }
106     }
107     return ret;
108 }
View Code

 

posted on 2015-08-22 14:26  _fukua  阅读(264)  评论(0编辑  收藏  举报