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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

hdu4750Count The Pairs(最小生成树找瓶颈边)

發布時間:2023/12/9 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu4750Count The Pairs(最小生成树找瓶颈边) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 /* 2 題意:就是給你一個圖,圖的每兩個點都有多條路徑,每一條路徑中都有一條最大邊, 3 所有最大邊的最小邊(也就是瓶頸邊)就是這兩點之間的val值!然后給你一個值f, 4 問有多少個頂點對的val>=f! (u,v) 和 (v, u)是不同的頂點對! 5 6 思路:最小生成樹(kruskral)那么每兩個節點(u,v)的瓶頸邊就是這一棵樹中u到v 7 的路徑中的最大邊值! 8 在利用并查集的過程中,A, B兩個集合,如果有u屬于A,v屬于B,且u-v可以將 9 A-B集合連接起來,因為邊值由小到大選取,那么以u-v邊為瓶頸邊的節點的個數 10 就是[A]*[B]*2; 11 12 注意:圖不一定是連通的,開始的時候當成了一棵樹,怎么改都不對! 13 */ 14 #include<iostream> 15 #include<cstring> 16 #include<cstdio> 17 #include<algorithm> 18 #define N 10105 19 #define M 500105 20 using namespace std; 21 int f[N]; 22 struct Edge{ 23 int u, v, w; 24 Edge(){} 25 Edge(int u, int v, int w){ 26 this->u=u; 27 this->v=v; 28 this->w=w; 29 } 30 }; 31 32 Edge edge[M]; 33 int dist[N]; 34 int rank[N]; 35 int cnt[N]; 36 int edgeN; 37 int sumN[N]; 38 int n, m; 39 40 bool cmp(Edge a, Edge b){ 41 return a.w < b.w; 42 } 43 44 int getFather(int x){ 45 return x==f[x] ? x : f[x]=getFather(f[x]); 46 } 47 48 bool Union(int a, int b){ 49 a=getFather(a); 50 b=getFather(b); 51 if(a!=b){ 52 cnt[++edgeN]=sumN[a]*sumN[b]*2;//記錄以這一條邊為瓶頸邊的節點對的個數 53 if(rank[a]>rank[b]){ 54 f[b]=a; 55 sumN[a]+=sumN[b];//將b集合放入到a集合中去 56 } 57 else{ 58 f[a]=b; 59 sumN[b]+=sumN[a];//將a集合放入到b集合中去 60 ++rank[b]; 61 } 62 return true; 63 } 64 return false; 65 } 66 67 void Kruskral(){ 68 edgeN=0; 69 sort(edge, edge+m, cmp); 70 for(int i=1; i<=n; ++i) 71 f[i]=i, rank[i]=0, sumN[i]=1; 72 for(int i=0; i<m; ++i) 73 if(Union(edge[i].u, edge[i].v)) 74 dist[edgeN]=edge[i].w;//記錄最小生成樹中的邊值 75 cnt[edgeN+1]=0; 76 for(int i=edgeN; i>=1; --i)//統計大于等于第i條邊為瓶頸邊邊值的所有節點對的對數 77 cnt[i]+=cnt[i+1]; 78 } 79 80 int main(){ 81 int p; 82 while(scanf("%d%d", &n, &m)!=EOF){ 83 for(int i=0; i<m; ++i){ 84 int u, v, w; 85 scanf("%d%d%d", &u, &v, &w); 86 edge[i]=Edge(u+1, v+1, w); 87 } 88 Kruskral(); 89 scanf("%d", &p); 90 while(p--){ 91 int x; 92 scanf("%d", &x); 93 int index=lower_bound(dist+1, dist+edgeN+1, x)-dist; 94 if(index>edgeN) printf("0\n"); 95 else printf("%d\n", cnt[index]); 96 } 97 } 98 return 0; 99 }

//如果最后只有一棵樹的話,這樣做就可以了!沒想到可能不是僅僅一棵樹
1
#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #define N 10105 6 #define M 500105 7 using namespace std; 8 int f[N]; 9 struct Edge{ 10 int u, v, w; 11 Edge(){} 12 Edge(int u, int v, int w){ 13 this->u=u; 14 this->v=v; 15 this->w=w; 16 } 17 }; 18 19 Edge edge[M]; 20 int dist[N]; 21 int rank[N]; 22 int cnt[N]; 23 int edgeN; 24 25 int n, m; 26 27 bool cmp(Edge a, Edge b){ 28 return a.w < b.w; 29 } 30 31 int getFather(int x){ 32 return x==f[x] ? x : f[x]=getFather(f[x]); 33 } 34 35 bool Union(int a, int b){ 36 a=getFather(a); 37 b=getFather(b); 38 if(a!=b){ 39 if(rank[a]>rank[b]) 40 f[b]=a; 41 else{ 42 f[a]=b; 43 ++rank[b]; 44 } 45 return true; 46 } 47 return false; 48 } 49 50 void Kruskral(){ 51 edgeN=0; 52 sort(edge, edge+m, cmp); 53 for(int i=1; i<=n; ++i) 54 f[i]=i, rank[i]=0; 55 for(int i=0; i<m; ++i) 56 if(Union(edge[i].u, edge[i].v)) 57 dist[++edgeN]=edge[i].w; 58 cnt[edgeN+1]=0; 59 for(int i=edgeN; i>=1; --i){ 60 cnt[i]=i*2; 61 cnt[i]+=cnt[i+1]; 62 } 63 } 64 65 int main(){ 66 int p; 67 while(scanf("%d%d", &n, &m)!=EOF){ 68 for(int i=0; i<m; ++i){ 69 int u, v, w; 70 scanf("%d%d%d", &u, &v, &w); 71 edge[i]=Edge(u+1, v+1, w); 72 } 73 Kruskral(); 74 scanf("%d", &p); 75 while(p--){ 76 int x; 77 scanf("%d", &x); 78 int index=lower_bound(dist+1, dist+edgeN+1, x)-dist; 79 if(index>edgeN) printf("0\n"); 80 else printf("%d\n", cnt[index]); 81 } 82 } 83 return 0; 84 }

?

?

總結

以上是生活随笔為你收集整理的hdu4750Count The Pairs(最小生成树找瓶颈边)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。