poj 1679 次最小生成树
来源:互联网 发布:中国出口白酒数据 编辑:程序博客网 时间:2024/06/08 03:08
/******************************************************************** ** @file poj 1679.cpp ** @date Wed Apr 27 14:47:06 2011 ** @brief ***********次最小生成树********** ** ** ********************************************************************/#include<iostream>#include<cstring>#include<algorithm>using namespace std;#define MAX 103#define INF 1e9struct node { int u,v,w;}edge[MAX*MAX];int n,m;int father[MAX],MIN=0;int map[MAX];bool cmp(struct node u,struct node v){ return u.w<v.w;} int find(int u){ return father[u]==u?u:father[u]=find(father[u]);}bool canUnion(int u,int v){ int a=find(u); int b=find(v); if(a==b)return false; else father[a]=b; return true;}bool kruskal(){ MIN=0; int sum=0;int index=0; for(int i=1;i<=n;++i)father[i]=i; for(int i=1;i<=m;++i){/*先求出最小生成树 */ if(canUnion(edge[i].u,edge[i].v)){ MIN+=edge[i].w;map[++index]=i;/*map记录了那些边被用在最小生成树中*/ } } int cnt=0;int secondMIN=INF; for(int i=1;i<=index;++i){//每次 sum=0;cnt=0; for(int j=1;j<=n;++j)father[j]=j; for(int j=1;j<=m;++j) { if(map[i]==j)continue;//每次去掉最小生成树上的边map[i] if(canUnion(edge[j].u,edge[j].v)) { sum+=edge[j].w; cnt++; } } if(cnt!=n-1)sum+=INF; if(secondMIN>sum)secondMIN=sum;//secondMIn保留了次最小生成树的值 } if(secondMIN==MIN)return false; else return true;}int main(int argc, char *argv[]){ int t;cin>>t; for(int i=0;i<t;++i){ cin>>n>>m; for(int j=1;j<=m;++j) cin>>edge[j].u>>edge[j].v>>edge[j].w; sort(edge+1,edge+1+m,cmp); if(kruskal())cout<<MIN<<endl; else cout<<"Not Unique!"<<endl; } return 0;}