题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2988
思路:水题,kruskal求最小生成树之后,直接用总权值减去即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 222222 7 typedef long long LL; 8 struct Edge{ 9 int u,v,w; 10 }edge[MAXN]; 11 LL ans,sum; 12 int parent[MAXN]; 13 int n,m; 14 15 int cmp(const Edge &p,const Edge &q){ 16 return p.w<q.w; 17 } 18 19 int Find(int x){ 20 int s; 21 for(s=x;parent[s]>=0;s=parent[s]) 22 ; 23 while(s!=x){ 24 int tmp=parent[x]; 25 parent[x]=s; 26 x=tmp; 27 } 28 return s; 29 } 30 31 void Union(int R1,int R2){ 32 int r1=Find(R1),r2=Find(R2); 33 if(r1==r2)return ; 34 if(parent[r1]<parent[r2]){ 35 parent[r1]+=parent[r2]; 36 parent[r2]=r1; 37 }else { 38 parent[r2]+=parent[r1]; 39 parent[r1]=r2; 40 } 41 } 42 43 LL Kruskal(){ 44 LL s=0; 45 for(int i=0;i<m;i++){ 46 int u=edge[i].u,v=edge[i].v,w=edge[i].w; 47 if(Find(u)!=Find(v)){ 48 s+=w; 49 Union(u,v); 50 } 51 } 52 return s; 53 } 54 55 int main(){ 56 while(~scanf("%d%d",&n,&m)&&(n+m)){ 57 memset(parent,-1,sizeof(parent[0])*n); 58 ans=0; 59 for(int i=0;i<m;i++){ 60 scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); 61 ans+=edge[i].w; 62 } 63 sort(edge,edge+m,cmp); 64 sum=Kruskal(); 65 printf("%I64d\n",ans-sum); 66 } 67 return 0; 68 }