Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 20737 | Accepted: 7281 |
Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
题意:判断最小生成树是否唯一;
分析:最小生成树的值和次小生成树的值相等则不唯一;
程序:
#include"stdio.h" #include"string.h" #define inf 100000000 #define M 1111 int G[M][M],maxd[M][M],use[M],dis[M],pre[M],vis[M][M]; int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int dij(int u,int n) { int ans=0,i,j; memset(use,0,sizeof(use)); memset(maxd,0,sizeof(maxd));//记录不在任意两点在在生成树的路径中的最长边 memset(vis,0,sizeof(vis));//标记边是否在生成树里面 for(i=1;i<=n;i++) { dis[i]=G[u][i]; pre[i]=u;//记录父节点 } dis[u]=0; use[u]=1; for(i=1;i<n;i++) { int mini=inf; int tep=-1; for(j=1;j<=n;j++) { if(!use[j]&&dis[j]<mini) { mini=dis[j]; tep=j; } } if(tep==-1)break; use[tep]=1; vis[tep][pre[tep]]=vis[pre[tep]][tep]=1; ans+=mini; for(j=1;j<=n;j++) { if(!use[j]&&dis[j]>G[tep][j]) { dis[j]=G[tep][j]; pre[j]=tep; } if(j!=tep) maxd[tep][j]=maxd[j][tep]=max(mini,maxd[pre[tep]][j]);//更新 } } return ans; } int main() { int T,m,n,i,j; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=n;j++) G[i][j]=inf; while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); if(G[a][b]>c) G[a][b]=G[b][a]=c; } int ans=dij(1,n); int cnt=inf; for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(G[i][j]<inf&&vis[i][j]==0) { cnt=min(cnt,ans+G[i][j]-maxd[i][j]); } } } if(ans==cnt) printf("Not Unique!\n"); else printf("%d\n",ans); } return 0; }