poj1679——The Unique MST

本文介绍了一种通过求解次小生成树来判断给定图的最小生成树是否唯一的算法实现。使用Prim算法进行核心计算,并通过维护额外的数据结构来确保算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给定N和M,表示N个顶点和M条边,问最小生成树是否唯一。

思路:求次小生成树,判断是否和最小生成树一样。

参考http://blog.youkuaiyun.com/sunbaigui/archive/2009/10/11/4653271.aspx

以前prim的主循环都做了N次,这次严谨点,只做N-1次!

主要理解:for(j=1;j<=n;j++) { maxlen[pre[k]][k]=maxlen[k][pre[k]]=g[pre[k]][k]; if(vis[j]==false) { maxlen[j][k]=maxlen[k][j]=maxlen[j][k]>maxlen[pre[k]][k]?maxlen[j][k]:maxlen[pre[k]][k]; } }

#include<iostream> #include<cstdio> #include<cstring> #define maxcost 999999999 using namespace std; int n,m; int g[110][110],dist[110],vis[110],maxlen[110][110],pre[110]; int prim() { int min,dis,i,j,k; int ans=0; for(i=1;i<=n;i++) for(j=1;j<=n;j++) maxlen[i][j]=-maxcost; for(i=1;i<=n;i++) { pre[i]=1; dist[i]=g[1][i]; vis[i]=true; } vis[1]=false;dist[1]=0; for(i=1;i<n;i++) { min=maxcost;k=1; for(j=1;j<=n;j++) if(vis[j]&&dist[j]<min) { min=dist[j];k=j; } vis[k]=false; ans+=min; for(j=1;j<=n;j++) { maxlen[pre[k]][k]=maxlen[k][pre[k]]=g[pre[k]][k]; if(vis[j]==false) { maxlen[j][k]=maxlen[k][j]=maxlen[j][k]>maxlen[pre[k]][k]?maxlen[j][k]:maxlen[pre[k]][k]; } } for(j=1;j<=n;j++) if(vis[j]&&dist[j]>g[k][j]) { dist[j]=g[k][j]; pre[j]=k; } } for(i=1;i<=n;i++) for(j=1+1;j<=n;j++) { if(pre[i]==j||pre[j]==i)//已用 {} else if(maxlen[i][j]==g[i][j]) return -1; } return ans; } int main() { int t,x,y,dis; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) g[i][j]=maxcost; while(m--) { scanf("%d%d%d",&x,&y,&dis); g[x][y]=g[y][x]=dis; } int k=prim(); if(k==-1) printf("Not Unique!\n"); else printf("%d\n",k); } return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值