标签:nyoj修路方案
南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路。
现在已经知道哪些城市之间可以修路,如果修路,花费是多少。
现在,军师小工已经找到了一种修路的方案,能够使各个城市都联通起来,而且花费最少。
但是,南将军说,这个修路方案所拼成的图案很不吉利,想让小工计算一下是否存在另外一种方案花费和刚才的方案一样,现在你来帮小工写一个程序算一下吧。
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
No Yes
次小生成树讲解
#include<cstdio> #include<cstdlib> #include<cstring> #define inf 0x3f3f3f3f using namespace std; const int max=505; int map[max][max],use[max][max],f[max][max]; int low[max],vis[max],pre[max],n,sum1,sum2; void prime(){ int pos,i,j,result=0,min;sum1=0; memset(vis,0,sizeof(vis)); memset(f,0,sizeof(f)); pos=1;vis[pos]=1; for(i=1;i<=n;++i){ low[i]=map[pos][i]; pre[i]=1; }low[1]=0; for(j=1;j<=n;++j){ min=inf; for(i=1;i<=n;++i){ if(!vis[i]&&min>low[i]){ min=low[i];pos=i; } } if(min==inf)break; use[pre[pos]][pos]=use[pos][pre[pos]]=0; sum1+=min;vis[pos]=1; for(i=1;i<=n;++i){ if(vis[i]){ f[i][pos]=f[pos][i]=f[i][pre[pos]]>map[pre[pos]][pos]?f[i][pre[pos]]:map[pre[pos]][pos]; } if(!vis[i]&&low[i]>map[pos][i]){ low[i]=map[pos][i]; pre[i]=pos; } } } } void second_prime(){ int i,j,result;sum2=inf; for(i=1;i<=n;++i){ for(j=1;j<=n;++j){ if(use[i][j]){ sum2=sum2<sum1-f[i][j]+map[i][j]?sum2:sum1-f[i][j]+map[i][j]; } } } } int main() { int k,m,i,j,l,a,b; scanf("%d",&k); while(k--){ memset(map,0x3f,sizeof(map)); memset(use,0,sizeof(use)); scanf("%d%d",&n,&m); for(i=1;i<=m;++i){ scanf("%d%d%d",&a,&b,&l); map[a][b]=map[b][a]=l; use[a][b]=use[b][a]=1; } prime(); second_prime(); sum1==sum2?printf("Yes\n"):printf("No\n"); } return 0; }
标签:nyoj修路方案
原文地址:http://blog.csdn.net/r1986799047/article/details/43374355