poj 1679

原题:

 

The Unique MST
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 8142 Accepted: 2736

Description

Given a connected undirected graph, tell if its minimum spanning tree is unique.

Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties:
1. V' = V.
2. T is connected and acyclic.

Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'.

Input

The first line contains a single integer t (1 <= t <= 20), the number of test cases. Each case represents a graph. It begins with a line containing two integers n and m (1 <= n <= 100), the number of nodes and edges. Each of the following m lines contains a triple (xi, yi, wi), indicating that xi and yi are connected by an edge with weight = wi. For any two nodes, there is at most one edge connecting them.

Output

For each input, if the MST is unique, print the total cost of it, or otherwise print the string 'Not Unique!'.

Sample Input

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

Sample Output

3
Not Unique!
     这道题的一般做法是先在原图中先构建出一个MST,然后将MST的每一条边存入一个结构体node数组中,里面记录该条边的两个端点和权值。
再用枚举的方法,每次循环逐个删除图中MST的一条边,看在此情况下改图是否仍能构造出一个MST使得其cost和原MST的cost相等。相等则输出
“Not Unique!”,若循环结束均无此情况出现,则可以输出原MST的cost。
       以下有两种基于prime算法的解题方法,但prime算法的处理不同,最终第一个算法AC,第二个WA了。。。囧,感兴趣的大牛可以把第二
个修改修改~~~
   1.
#include "stdio.h"
#include "string.h"
#define N 110
#define M 10000
#define INF 10000000
struct node
{
 int u,v,w;
}edge[M];
int map[N][N],d[M],dise[M];//dise[]数组记录每个顶点取到dis[]值时对应边的顶点
bool visit[N];
int n;
void MST_prim()
{
 int i,j,now,min_node,min_edge;
 int edge_num, k=0,flag=1,tflag=0;
 int ans=0;
 for(i=1;i<=n;i++) //第一次prime
  d[i]=INF;
 now=1;
 for(i=1;i<n;i++)
 {
  d[now]=-1;
  min_edge=INF;
  for(j=1;j<=n;j++)
            if(j!=now && d[j]>=0)
   {
                if(map[now][j]<d[j])
    {
                    d[j]=map[now][j];
     dise[j]=now;
    }
    if(d[j]<min_edge)
    {
                    min_edge=d[j];
                    min_node=j;
                }
            }
  edge[k].u=min_node; //记录原MST的边
  edge[k].v=dise[min_node];
  edge[k].w=map[edge[k].u][edge[k].v];
  k++;
  now=min_node;
  ans+=min_edge;
 }
 edge_num=k;
  for(k=0;k<edge_num;k++) //第二次prime,找其他的MST
  {
        map[edge[k].u][edge[k].v]=INF;
        map[edge[k].v][edge[k].u]=INF;
   if(i!=0)
   {
   map[edge[k-1].u][edge[k-1].v] = edge[k-1].w;
            map[edge[k-1].v][edge[k-1].u] = edge[k-1].w;
        }
  for(i=1;i<=n;i++)
   d[i]=INF;
  int ans1=0;
  now=1;
        for(i=1;i<n;i++){
            d[now]=-1;
            min_edge=INF;
            for(j = 1; j <= n; j ++)
                if(j!=now && d[j]> 0){
                    if(map[now][j]<d[j])
                        d[j]=map[now][j];
                    if(d[j]<min_edge){
                        min_edge=d[j];
                        min_node=j;
                    }
                }
   if(min_edge==INF)
   {
    flag=0;
    break;
   }
   now=min_node;
            ans1+=min_edge;
  }
  if(flag && ans1==ans) {tflag=1;break;}
  }
  if(tflag) printf("Not Unique!/n");
  else printf("%d/n",ans);
}
int main()
{
 int t,m;
 scanf("%d",&t);
 for(int q=0;q<t;q++)
 {
  int x,y,z;
  int i;
  scanf("%d%d",&n,&m);
  for(int j=1;j<=n;j++)
   for(i=1;i<=n;i++)
   {
    if(i==j) map[j][i]=0;
    else map[j][i]=INF;
   }
  for(i=0;i<m;i++)
  {
   scanf("%d%d%d",&x,&y,&z);
   map[x][y]=z;
   map[y][x]=z;
  }
  MST_prim();
 }
 return 0;
}
2.
#include "stdio.h"
#include "string.h"
#define N 110
#define M 10000
#define INF 10000000
struct node
{
 int u,v,w;
}edge[M];
int map[N][N],d[M],dise[M];
bool visit[N];
int n;
void MST_prim()
{
 int i,j;
 int k;
 int all_cost=0,all_cost1;
 int flag=0,edge_num=1;
 for(i=1;i<n;i++) //第一次prime
 {
  int min=INF;
  for(j=1;j<=n;j++)
   if(visit[j]==false && d[j]<min) {min=d[j];k=j;}
  all_cost+=min;
  visit[k]=true;
  for(j=1;j<=n;j++)
   if(visit[j]==false && map[k][j]<d[j])
    d[j]=map[k][j];
  if(i==1) {edge[edge_num].u=1;edge[edge_num].v=k;edge[edge_num].w=map[edge[edge_num].u][edge[edge_num].v];}
  else {edge[edge_num].u=edge[edge_num-1].v;edge[edge_num].v=k;edge[edge_num].w=map[edge[edge_num].u][edge[edge_num].v];}
  edge_num++; //上面是记录MST各边的代码
 }
  for(int t=1;t<edge_num;t++) //第二次prime
 {
  all_cost1=0;
  map[edge[t].u][edge[t].v]=INF;
  map[edge[t].v][edge[t].u]=INF;
  if(t!=1)
  {
   map[edge[t-1].u][edge[t-1].v]=edge[t-1].w;
   map[edge[t-1].v][edge[t-1].u]=edge[t-1].w;
  }
 for(i=1;i<=n;i++)
   d[i]=map[1][i];
 memset(visit,false,sizeof(visit));
 visit[1]=true;
 for(i=1;i<n;i++)
 {
  int min=INF;
  for(j=1;j<=n;j++)
   if(visit[j]==false && d[j]<min) {min=d[j];k=j;}
  all_cost1+=min;
  visit[k]=true;
  for(j=1;j<=n;j++)
   if(visit[j]==false && map[k][j]<d[j])
    d[j]=map[k][j];
 }
 if(all_cost==all_cost1) {flag=1;break;}
 }
 if(flag) printf("Not Unique!/n");
 else
  printf("%d/n",all_cost);
}
int main()
{
 int t,m;
 scanf("%d",&t);
 for(int q=0;q<t;q++)
 {
  int x,y,z;
  int i;
  scanf("%d%d",&n,&m);
  for(int j=1;j<=n;j++)
   for(i=1;i<=n;i++)
   {
    if(i==j) map[j][i]=0;
    else map[j][i]=INF;
   }
  for(i=0;i<m;i++)
  {
   scanf("%d%d%d",&x,&y,&z);
   map[x][y]=z;
   map[y][x]=z;
  }
  for(i=1;i<=n;i++)
   d[i]=map[1][i];
  memset(visit,false,sizeof(visit));
  visit[1]=true;
  MST_prim();
 }
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值