POJ 1679 次小生成树
来源:互联网 发布:淘宝店铺装修永久模板 编辑:程序博客网 时间:2024/05/09 07:24
#include<stdio.h>#include<string.h>#include<iostream>#include<vector>#define M 105#define Max 10000000using namespace std;int n,m;int map[M][M];int max_val[M][M];//记录最小生成树中任意两点之间最大边的值int pre[M];bool v[M][M];int prime(){ int MIN[M]; bool visited[M]; int i,j,u,k; int min,ans=0; memset(visited,false,sizeof(visited)); memset(pre,0,sizeof(pre)); memset(max_val,0,sizeof(max_val)); for(i=1;i<=n;i++) MIN[i]=Max; MIN[1]=0; for(k=0;k<n;k++) { min=Max; for(i=1;i<=n;i++) { if(!visited[i]&&MIN[i]<min) { min=MIN[i]; u=i; } } int p=pre[u]; max_val[p][u]=min; v[p][u]=true;//是所求最小生成树中,标记为true v[u][p]=true; for(i=1;i<=n;i++) if(visited[i])//更新所有已在最小生成树中的点到u的max_val[i][u] max_val[i][u]=max_val[i][p]>max_val[p][u]?max_val[i][p]:max_val[p][u]; visited[u]=true; ans+=min; for(i=1;i<=n;i++) { if(!visited[i]&&MIN[i]>map[u][i]) { MIN[i]=map[u][i]; pre[i]=u;//如果u能把MIN[i]更新,则u是i的pre } } } return ans;}int main(){ int cas,i,j; int T,T1; bool flag; scanf("%d",&cas); while(cas--) { scanf("%d%d",&n,&m); for(i=0;i<=n;i++) for(j=0;j<=n;j++) map[i][j]=Max; for(i=0;i<m;i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); map[a][b]=map[b][a]=c; } memset(v,false,sizeof(v)); T=prime();//先求出一条最小生成树 flag=true; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(!v[i][j]&&map[i][j]!=Max)//找一条不在最小生成树中的边(能走通)去替换最小生成树中的一条边 { T1=T+map[i][j]-max_val[i][j]; if(T1==T) { flag=false; break; } } } if(flag==false) break; } if(flag) printf("%d\n",T); else printf("Not Unique!\n"); } return 0;}