【UVA 10600】 ACM Contest and Blackout(最小生成树和次小生成树)

【题意】

  n个点,m条边,求最小生成树的值和次小生成树的值。

Input
The Input starts with the number of test cases, T (1 < T < 15) on a line. Then T test cases follow. The
first line of every test case contains two numbers, which are separated by a space, N (3 < N < 100)
the number of schools in the city, and M the number of possible connections among them. Next M
lines contain three numbers Ai
, Bi
, Ci
, where Ci
is the cost of the connection (1 < Ci < 300) between
schools Ai and Bi
. The schools are numbered with integers in the range 1 to N.
Output
For every test case print only one line of output. This line should contain two numbers separated by a
single space – the cost of two the cheapest connection plans. Let S1 be the cheapest cost and S2 the
next cheapest cost. It’s important, that S1 = S2 if and only if there are two cheapest plans, otherwise
S1 < S2. You can assume that it is always possible to find the costs S1 and S2.
Sample Input
2
5 8
1 3 75
3 4 51
2 4 19
3 2 95
2 5 42
5 4 31
1 2 9
3 5 66
9 14
1 2 4
1 8 8
2 8 11
3 2 8
8 9 7
8 7 1
7 9 6
9 3 2
3 4 7
3 6 4
7 6 2
4 6 14
4 5 9
5 6 10
Sample Output
110 121
37 37

 

 

【分析】

  主要就是次小生成树咯。

  次小生成树一定是最小生成树删一边再加一条边。

  先求出最小生成树,然后n^2预处理两点的最小瓶颈路的值maxcost,然后枚举新加入的那条边然后替换边就好了。

  啊啊啊啊啊,忘了清bool哭瞎

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 #define Maxn 110
 9 #define INF 0xfffffff
10 
11 struct node
12 {
13     int x,y,c,next;
14     bool p;
15 }tt[Maxn*Maxn],t[Maxn];
16 int len;
17 int fa[Maxn],first[Maxn];
18 
19 bool cmp(node x,node y) {return x.c<y.c;}
20 int mymax(int x,int y) {return x>y?x:y;}
21 int mymin(int x,int y) {return x<y?x:y;}
22 
23 int ffa(int x)
24 {
25     if(fa[x]!=x) fa[x]=ffa(fa[x]);
26     return fa[x];
27 }
28 
29 void ins(int x,int y,int c)
30 {
31     t[++len].x=x;t[len].y=y;t[len].c=c;
32     t[len].next=first[x];first[x]=len;
33 }
34 
35 int n,m,mc[Maxn][Maxn];
36 bool np[Maxn];
37 
38 void dfs(int x,int f,int l)
39 {
40     for(int i=1;i<=n;i++) if(np[i])
41         mc[x][i]=mc[i][x]=mymax(mc[f][i],l);
42     np[x]=1;
43     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
44     {
45         dfs(t[i].y,x,t[i].c);
46     }
47 }
48 
49 int main()
50 {
51     int T;
52     scanf("%d",&T);
53     while(T--)
54     {
55         scanf("%d%d",&n,&m);
56         for(int i=1;i<=m;i++)
57         {
58             scanf("%d%d%d",&tt[i].x,&tt[i].y,&tt[i].c);
59             tt[i].p=0;
60         }
61         sort(tt+1,tt+1+m,cmp);
62         for(int i=1;i<=n;i++) fa[i]=i;
63         int cnt=0,a1=0,a2=INF;
64         len=0;
65         memset(first,0,sizeof(first));
66         for(int i=1;i<=m;i++)
67         {
68             if(ffa(tt[i].x)!=ffa(tt[i].y))
69             {
70                 fa[ffa(tt[i].x)]=ffa(tt[i].y);
71                 tt[i].p=1;
72                 cnt++;
73                 ins(tt[i].x,tt[i].y,tt[i].c);
74                 ins(tt[i].y,tt[i].x,tt[i].c);
75                 a1+=tt[i].c;
76             }
77             if(cnt==n-1) break;
78         }
79         memset(mc,0,sizeof(mc));
80         memset(np,0,sizeof(np));
81         dfs(1,0,0);
82         for(int i=1;i<=m;i++) if(!tt[i].p&&tt[i].x!=tt[i].y)
83         {
84             a2=mymin(a2,a1-mc[tt[i].x][tt[i].y]+tt[i].c);
85         }
86         printf("%d %d\n",a1,a2);
87     }
88     return 0;
89 }
View Code

 

2016-11-01 20:51:55

posted @ 2016-11-01 20:47  konjak魔芋  阅读(390)  评论(0编辑  收藏  举报