uva 10462 is there a second way left 代码

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

typedef long long ll;
const int maxn=110;
const int inf=0x3f3f3f3f;

struct {
int u,v,w;
bool operator < (const Edge &a)const{
return w<a.w;
}
}edge[maxn<<1];

int pre[maxn],used[maxn];

int find(int x)
{
return pre[x]==-1?x:x=find(pre[x]);
}

int kruskal(int n,int m,int pointed)
{
int cnt=0,sum=0;
memset(pre,-1,sizeof(pre));
for (int i=1;i<=m;i++)
{
if(i==pointed) continue;
int u=find(edge[i].u);
int v=find(edge[i].v);
if(u!=v)
{
pre[u]=v;//连在一颗树上
sum+=edge[i].w;
++cnt;
if(pointed==-1)//如果求最小生成树,则把编号为i的边加入到生成树中
used[cnt]=i;
if(cnt==n-1) return sum; //合并了n-1次,已成树,可直接返回
}
}
return cnt<(n-1)?inf:sum;
}

int main()
{
int T,n,m;
scanf("%d",&T);
for (int kase=1;kase<=T;kase++)
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
}
sort(edge+1,edge+1+m);
int t1=inf,t2=inf;
t1=kruskal(n,m,-1);//求最小生成树
for (int i=1;i<n;i++)//枚举删除每一条最小生成树的边,求次小生成树
{
int tmp=kruskal(n,m,used[i]);
t2=min(t2,tmp);
}
if(t1==inf)
{
printf("Case #%d : No wayn",kase);
}
else if(t2==inf)
{
printf("Case #%d : No second wayn",kase);
}
else
{
printf("Case #%d : %dn",kase,t2);
}
}
return 0;
}