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;}