日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu 4607 Park Visit 求树的直径

發(fā)布時間:2025/5/22 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu 4607 Park Visit 求树的直径 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4607

Claire and her little friend, ykwd, are travelling in Shevchenko's Park! The park is beautiful - but large, indeed. N feature spots in the park are connected by exactly (N-1) undirected paths, and Claire is too tired to visit all of them. After consideration, she decides to visit only K spots among them. She takes out a map of the park, and luckily, finds that there're entrances at each feature spot! Claire wants to choose an entrance, and find a way of visit to minimize the distance she has to walk. For convenience, we can assume the length of all paths are 1.
Claire is too tired. Can you help her? 題意描述:小伙伴在公園里玩,公園里有N個景點,由n-1條無向路徑連通(每條路徑長度為1)。現(xiàn)在小伙伴想?yún)⒂^其中k個景點,并且要求所走的路徑最短。求最短路徑。 算法分析:首先知道這是一個無向連通圖,形如樹形結構。假設公園里有一條很長的路徑,包含了比k大的景點個數(shù),這時我們要走完k個景點的最短路徑就是k-1(沿著這條路往下走即可),如果沒有k個呢,就要想著盡量少的景點在別的路徑(因為這條路徑上景點個數(shù)多,走到別的路徑還得回來繼續(xù)往下走)。由此,可以想到求樹的直徑就是了。(關于求解樹的直徑的證明網(wǎng)上也有很多) 求樹的直徑算法:樹的直徑是指樹的最長簡單路。 求法: 兩遍BFS :先任選一個起點BFS找到最長路的終點,再從終點進行BFS,則第二次BFS找到的最長路即為樹的直徑; 原理:設起點為u,第一次BFS找到的終點v一定是樹的直徑的一個端點 證明:1) 如果u 是直徑上的點,則v顯然是直徑的終點(因為如果v不是的話,則必定存在另一個點w使得u到w的距離更長,則于BFS找到了v矛盾) 2) 如果u不是直徑上的點,則u到v必然于樹的直徑相交(反證),那么交點到v 必然就是直徑的后半段了所以v一定是直徑的一個端點,所以從v進行BFS得到的一定是直徑長度 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #define inf 0x7fffffff 9 using namespace std; 10 const int maxn=100000+10; 11 const int M = 100000+10; 12 13 int n,m; 14 struct node 15 { 16 int v,w; 17 int next; 18 }edge[M*3]; 19 int head[maxn],edgenum; 20 21 void add(int u,int v,int w) 22 { 23 edge[edgenum].v=v ;edge[edgenum].w=w ; 24 edge[edgenum].next=head[u] ;head[u]=edgenum++ ; 25 26 edge[edgenum].v=u ;edge[edgenum].w=w ; 27 edge[edgenum].next=head[v] ;head[v]=edgenum++ ; 28 } 29 30 int vis[maxn],d[maxn]; 31 int bfs(int from) 32 { 33 queue<int> Q; 34 Q.push(from); 35 memset(d,-1,sizeof(d)); 36 memset(vis,0,sizeof(vis)); 37 d[from]=1; 38 vis[from]=1; 39 int maxlen=-1,k=0; 40 while (!Q.empty()) 41 { 42 int u=Q.front() ;Q.pop() ; 43 for (int i=head[u] ;i!=-1 ;i=edge[i].next) 44 { 45 int v=edge[i].v; 46 if (!vis[v]) 47 { 48 vis[v]=1; 49 d[v]=d[u]+1; 50 if (d[v]>maxlen) 51 { 52 maxlen=d[v]; 53 k=v; 54 } 55 Q.push(v); 56 } 57 } 58 } 59 return k; 60 } 61 62 int main() 63 { 64 int t; 65 scanf("%d",&t); 66 while (t--) 67 { 68 memset(head,-1,sizeof(head)); 69 edgenum=0; 70 int a,b; 71 scanf("%d%d",&n,&m); 72 for (int i=1 ;i<=n-1 ;i++) 73 { 74 scanf("%d%d",&a,&b); 75 add(a,b,1); 76 } 77 int v=bfs(1); 78 int u=bfs(v); 79 int maxlen=d[u]; 80 //cout<<"debug= "<<maxlen<<endl; 81 for (int i=0 ;i<m ;i++) 82 { 83 scanf("%d",&a); 84 if (a<=maxlen) printf("%d\n",a-1); 85 else printf("%d\n",maxlen-1+(a-maxlen)*2); 86 } 87 } 88 return 0; 89 }

?

轉載于:https://www.cnblogs.com/huangxf/p/4366979.html

《新程序員》:云原生和全面數(shù)字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的hdu 4607 Park Visit 求树的直径的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。