您的位置:首页 > 理论基础 > 数据结构算法

CSU 1541- There is No Alternative(克鲁斯卡尔)

2015-11-10 19:07 501 查看
F - There is No AlternativeTime Limit:3000MS     Memory Limit:262144KB     64bit IO Format:%lld & %lluSubmit Status Practice CSU1541Description Input Output Sample Input
4 4
1 2 3
1 3 3
2 3 3
2 4 3
Sample Output
1 3
题意:
这题就是求哪一条边是必须要用的才能构成最小生成树,之后再将其数值全部加起来就是答案了。
思路:
首先要找出最小生成树的总和是多少,然后是将构成那颗树的所有边都存起来,之后再删除一条边,看能否又找到总和相同的树,如果能就说明我可以用另外的边去代替被删除的边,即不是不可替代的边。
AC代码:
#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<vector>typedef unsigned long long ll;using namespace std;#define T 1500000int n,m,c;int par[T];int nu[T];struct node{int u,v,w;bool operator<(const node& a)const{return w<a.w;}}e[T];int find(int x){int s = x;for(;s!=par[s];s=par[s]);while(s!=x){int tmp = par[x];par[x] = s;x = tmp;}return s;}int kruskal(int x){for(int i=0;i<=n;++i){par[i] = i;}int num = 0, cost = 0;for(int i=0;i<m;++i){if(x==i)continue;int tx = find(e[i].u),ty = find(e[i].v);if(tx!=ty){par[tx] = ty;cost += e[i].w;num++;if(x==-1)nu[c++] = i;}if(num==n-1)break;}return cost;}int main(){#ifdef zscfreopen("input.txt","r",stdin);#endifint i;while(~scanf("%d%d",&n,&m)){c = 0;for(i=0;i<m;++i){scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);}sort(e,e+m);int w1 = kruskal(-1),w2,cost=0,cnt=0;for(i=0;i<c;++i){w2 = kruskal(nu[i]);if(w2!=w1){cost += e[nu[i]].w;cnt++;}}printf("%d %d\n",cnt,cost);}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 并查集