NYOJ 118 修路方案 (次小生成树--prime)

来源:互联网 发布:ubuntu uefi启动盘 编辑:程序博客网 时间:2024/05/17 09:29

修路方案

时间限制: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)
样例输入
23 31 2 12 3 23 1 34 41 2 22 3 23 4 24 1 2
样例输出
NoYes





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;  }  



0 0
原创粉丝点击