hiho 1050 树的直径
#1050 : 树中的最长路
描述
上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅仅可以拼凑成一棵二叉树!还可以拼凑成一棵多叉树——好吧,其实就是更为平常的树而已。
但是不管怎么说,小Ho喜爱的玩具又升级换代了,于是他更加爱不释手(其实说起来小球和木棍有什么好玩的是吧= =)。小Ho手中的这棵玩具树现在由N个小球和N-1根木棍拼凑而成,这N个小球都被小Ho标上了不同的数字,并且这些数字都是出于1..N的范围之内,每根木棍都连接着两个不同的小球,并且保证任意两个小球间都不存在两条不同的路径可以互相到达。总而言之,是一个相当好玩的玩具啦!
但是小Hi瞧见小Ho这个样子,觉得他这样沉迷其中并不是一件好事,于是寻思着再找点问题让他来思考思考——不过以小Hi的水准,自然是手到擒来啦!
于是这天食过早饭后,小Hi便对着又拿着树玩具玩的不亦乐乎的小Ho道:“你说你天天玩这个东西,我就问你一个问题,看看你可否知道?”
“不好!”小Ho想都不想的拒绝了。
“那你就继续玩吧,一会回国的时候我不叫上你了~”小Hi严肃道。
“诶!别别别,你说你说,我听着呢。”一向习惯于开启跟随模式的小Ho忍不住了,马上喊道。
小Hi满意的点了点头,随即说道:“这才对嘛,我的问题很简单,就是——你这棵树中哪两个结点之间的距离最长?当然,这里的距离是指从一个结点走到另一个结点经过的木棍数。”。
“啊?”小Ho低头看了看手里的玩具树,困惑了。
提示一:路总有折点,路径也不例外!输入
每个测试点(输入文件)有且仅有一组测试数据。
每组测试数据的第一行为一个整数N,意义如前文所述。
每组测试数据的第2~N行,每行分别描述一根木棍,其中第i+1行为两个整数Ai,Bi,表示第i根木棍连接的两个小球的编号。
对于20%的数据,满足N<=10。
对于50%的数据,满足N<=10^3。
对于100%的数据,满足N<=10^5,1<=Ai<=N, 1<=Bi<=N
小Hi的Tip:那些用数组存储树边的记得要开两倍大小哦!
输出
对于每组测试数据,输出一个整数Ans,表示给出的这棵树中距离最远的两个结点之间相隔的距离。
- 样例输入
-
8 1 2 1 3 1 4 4 5 3 6 6 7 7 8
- 样例输出
-
6
//一棵树的直径就是这棵树上存在的最长路径。 // 任意两点间有唯一路径的无向图是树 #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <string> #include <string> #include <map> #include <cmath> #include <set> #include <algorithm> #include <queue> using namespace std; const int N=1e5+9; int ans; bool vis[N]; int dis[N]; int n,point; struct Node{ int to,w; Node(){} Node(int TO,int W){ to=TO; w=W; } }nod[N]; vector<Node>ve[N]; int bfs(int u) { memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); queue<int>que; que.push(u); vis[u]=1; point=0; while(!que.empty()){ int v=que.front(); que.pop(); if(ans<dis[v]){ ans=dis[v]; point=v; } for(int i=0;i<ve[v].size();i++){//这是树,直接走就可以了。 Node tmp=ve[v][i]; int w=tmp.to; if(!vis[w]){ vis[w]=1; dis[w]=dis[v]+tmp.w; que.push(w); } } } return point; } int main() { while(~scanf("%d",&n)){ int x,y; for(int i=0;i<n-1;i++){ scanf("%d%d",&x,&y); ve[x].push_back(Node(y,1)); ve[y].push_back(Node(x,1)); } ans=0; //int point=bfs(1); bfs(1); ans=0; //cout<<point<<endl; bfs(point); printf("%d\n",ans);//树的直径 for(int i=1;i<=n;i++) { ve[i].clear(); } } return 0; }
Nordic Collegiate Programming Contest 2015
A. Adjoin the Networks
One day your boss explains to you that he has a bunch of computer networks that are currently unreachable from each other, and he asks you, the cable expert's assistant, to adjoin the networks to each other using new cables. Existing cables in the network cannot be touched.
He has asked you to use as few cables as possible, but the length of the cables used does not matter to him, since the cables are optical and the connectors are the expensive parts. Your boss is rather picky on cable usage, so you know that the already existing networks have as few cables as possible.
Due to your humongous knowledge of computer networks, you are of course aware that the latency for an information packet travelling across the network is proportional to the number of hops the packet needs, where a hop is a traversal along a single cable. And since you believe a good solution to your boss' problem may earn you that long wanted promotion, you decide to minimise the maximum number of hops needed between any pair of network nodes.
Input Format
On the first line, you are given two positive integers, the number 1 \le c \le 10^51≤c≤105 of computers and the number 0 \le l \le c - 10≤l≤c−1 of existing cables. Then follow ll lines, each line consisting of two integers aa and bb, the two computers the cables connect. You may assume that every computer has a unique name between 00 and n - 1n−1.
Output Format
The maximum number of hops in the resulting network.
样例输入1
6 4 0 1 0 2 3 4 3 5
样例输出1
3
样例输入2
11 9 0 1 0 3 0 4 1 2 5 4 6 4 7 8 7 9 7 10
样例输出2
4
题目来源
Nordic Collegiate Programming Contest 2015
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string> 10 #include <cmath> 11 #include <cstdlib> 12 #include <ctime> 13 using namespace std; 14 typedef long long ll; 15 const int N=1e5+9; 16 bool vis1[N],vis2[N];//同步进行 17 int c,l; 18 struct Node{ 19 int to,w; 20 Node(){} 21 Node(int TO,int W){ 22 to=TO; 23 w=W; 24 } 25 }; 26 vector<Node>ve[N]; 27 int ans[N],dis[N]; 28 int bfs1(int x) 29 { 30 queue<int>q; 31 vis1[x]=1; 32 dis[x]=0;//这样dis 就不用清0了。 33 q.push(x); 34 int ret=0,point=0; 35 while(!q.empty()){ 36 int v=q.front(); 37 q.pop(); 38 if(ret<dis[v]){ 39 ret=dis[v]; 40 point=v; 41 } 42 for(int i=0;i<ve[v].size();i++){ 43 Node tmp=ve[v][i]; 44 int w=tmp.to; 45 if(!vis1[w]){ 46 vis1[w]=1; 47 dis[w]=dis[v]+tmp.w; 48 q.push(w); 49 } 50 } 51 } 52 return point; 53 } 54 int bfs2(int x) 55 { 56 queue<int>q; 57 vis2[x]=1; 58 dis[x]=0; 59 q.push(x); 60 int ret=0,point=0; 61 while(!q.empty()){ 62 int v=q.front(); 63 q.pop(); 64 if(ret<dis[v]){ 65 ret=dis[v]; 66 point=v; 67 } 68 for(int i=0;i<ve[v].size();i++){ 69 Node tmp=ve[v][i]; 70 int w=tmp.to; 71 if(!vis2[w]){ 72 vis2[w]=1; 73 dis[w]=dis[v]+tmp.w; 74 q.push(w); 75 } 76 } 77 } 78 return point; 79 } 80 bool cmp(int a,int b){ 81 return a>b; 82 } 83 int main() 84 { 85 scanf("%d%d",&c,&l); 86 int x,y; 87 for(int i=0;i<l;i++){ 88 scanf("%d%d",&x,&y); 89 ve[x].push_back(Node(y,1)); 90 ve[y].push_back(Node(x,1)); 91 } 92 int t=0; 93 for(int i=0;i<c;i++){ 94 if(!vis1[i])//访问过的不再重复 95 { 96 int u=bfs1(i); 97 int v=bfs2(u); 98 ans[t++]=dis[v]; 99 } 100 } 101 sort(ans,ans+t,cmp); 102 //只能是下面三种情况 103 int x1=ans[0]; 104 int y1=(ans[0]+1)/2+(ans[1]+1)/2+1; 105 int z1=(ans[1]+1)/2+(ans[2]+1)/2+2;//l==0时也正确,所有点围成半径为1的圆 106 int MAX=max(x1,max(y1,z1)); 107 //其他的连在最长直径的子树上,并以圆的形式放置 108 printf("%d\n",MAX); 109 return 0; 110 }