标签: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