<题目链接>
题目大意:
给定一张无向图,判断其最小生成树是否唯一。
解题分析:
对图中每条边,扫描其它边,如果存在相同权值的边,则标记该边;用kruskal求出MST。
如果MST中无标记的边,则该MST唯一;否则,在MST中依次去掉标记的边,再求MST,若求得MST权值和原来的MST 权值相同,则MST不唯一。
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N=11000; int n,m,cnt; int parent[N]; bool flag; struct EDGE { int u,v,w; int eq,used,del; } edge[N]; bool cmp(EDGE a,EDGE b) { return a.w<b.w; } int Find(int x) { if(parent[x] != x) parent[x] = Find(parent[x]); return parent[x]; } void Union(int x,int y) { x = Find(x); y = Find(y); if(x == y) return; parent[y] = x; } int Kruskal(){ for(int i=0; i<=10005; i++)parent[i]=i; int sum=0,num=0; for(int i=0;i<m;i++){ if(edge[i].del==1)continue; int u=edge[i].u;int v=edge[i].v;int w=edge[i].w; if(Find(u)!=Find(v)){ sum+=w; if(!flag)edge[i].used=1; num++; Union(u,v); } if(num>=n-1)break; } return sum; } int main() { int t,d; cin>>t; while(t--) { cnt=0; cin>>n>>m; for(int i=0; i<m; i++) { cin>>edge[i].u>>edge[i].v>>edge[i].w; edge[i].del=0; edge[i].used=0; edge[i].eq=0; //判断是否有和它长度相同的边 } for(int i=0;i<m;i++){ for(int j=0;j<m;j++){ if(i==j)continue; if(edge[i].w==edge[j].w)edge[i].eq=1; } } sort(edge,edge+m,cmp); flag=false; cnt=Kruskal(); flag=true; bool fp=false; for(int i=0;i<m;i++){ if(edge[i].used==1&&edge[i].eq==1){ edge[i].del=1; int s=Kruskal(); if(s==cnt){ fp=true; printf("Not Unique!\n"); break; } edge[i].del=0; } } if(!fp)cout<<cnt<<endl; } return 0; }
2018-10-01
原文地址:https://www.cnblogs.com/00isok/p/9735898.html
时间: 2024-10-08 23:04:49