修路方案
时间限制:3000 ms | 内存限制:65535 KB
难度:5
- 描述
-
南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路。
现在已经知道哪些城市之间可以修路,如果修路,花费是多少。
现在,军师小工已经找到了一种修路的方案,能够使各个城市都联通起来,而且花费最少。
但是,南将军说,这个修路方案所拼成的图案很不吉利,想让小工计算一下是否存在另外一种方案花费和刚才的方案一样,现在你来帮小工写一个程序算一下吧。
- 输入
- 第一行输入一个整数T(1<T<20),表示测试数据的组数
每组测试数据的第一行是两个整数V,E,(3<V<500,10<E<200000)分别表示城市的个数和城市之间路的条数。数据保证所有的城市都有路相连。
随后的E行,每行有三个数字A B L,表示A号城市与B号城市之间修路花费为L。 输出 - 对于每组测试数据输出Yes或No(如果存在两种以上的最小花费方案则输出Yes,如果最小花费的方案只有一种,则输出No) 样例输入
-
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
- 第一行输入一个整数T(1<T<20),表示测试数据的组数
ac代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#define INF 0xfffffff
#define MAXN 550
#define MAX(a,b) a>b?a:b
#define MIN(a,b) a>b?b:a
using namespace std;
int v[MAXN];
int pre[MAXN];
int pri[MAXN][MAXN];
int map[MAXN][MAXN];
int dis[MAXN];
int n;
void prime()
{
int i,j,k,M;
memset(v,0,sizeof(v));
memset(map,0,sizeof(map));
for(i=1;i<=n;i++)
{
dis[i]=pri[1][i];
pre[i]=1;
}
dis[1]=0;
v[1]=1;
for(i=1;i<n;i++)
{
M=INF;
for(j=1;j<=n;j++)
{
if(!v[j]&&dis[j]<M)
{
M=dis[j];
k=j;
}
}
if(M==INF)
break;
v[k]=1;
map[k][pre[k]]=map[pre[k]][k]=M;
for(j=1;j<=n;j++)
if(v[j])
map[j][k]=map[k][j]=MAX(M,map[j][pre[k]]);
for(j=1;j<=n;j++)
{
if(!v[j]&&dis[j]>pri[k][j])
{
dis[j]=pri[k][j];
pre[j]=k;
}
}
}
}
int main()
{
int t,m;
int i,j;
int a,b,c;
scanf("%d",&t);
while(t--)
{
int bz=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
pri[i][j]=INF;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
pri[a][b]=pri[b][a]=c;
}
prime();
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
if(pre[i]==j||pre[j]==i)
continue;
if(map[i][j]==pri[i][j])
{
bz=1;
break;
}
}
}
if(bz)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}