首页 > 代码库 > hdu4750Count The Pairs(最小生成树找瓶颈边)
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 1010519 #define M 50010520 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(最小生成树找瓶颈边)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。