(beginer) 最小生成树 UVA 10600 ACM Contest and Blackout

来源:互联网 发布:鬼影 电影 知乎 编辑:程序博客网 时间:2024/05/16 09:18

Problem A

ACM contest and Blackout

 

In order to prepare the “The First National ACM School Contest”(in 20??) the major of the city decided to provide all the schools with a reliable source of power. (The major is really afraid of blackoutsJ). So, in order to do that, power station “Future” and one school (doesn’t matter which one) must be connected; in addition, some schools must be connected as well.

 

You may assume that a school has a reliable source of power if it’s connected directly to “Future”, or to any other school that has a reliable source of power. You are given the cost of connection between some schools. The major has decided to pick out two the cheapest connection plans – the cost of the connection is equal to the sum of the connections between the schools. Your task is to help the major – find the cost of the two cheapest connection plans.

 

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

Sample Output

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

110 121

37 37


题意:找出最小生成树和次小生成树的长度。可能是相等的。

思路:首先找出最小生成树,然后在这个树中求出任意两点之间的最大边权,然后在枚举没有加进最小生成树的边中加边进来,假设加进来的边是(u,v) 那么我们从原来的的生成树中删掉u->v的路径中最大的边。

代码:
#include<iostream>#include<stdio.h>#include<cstring>#include<string.h>#include<algorithm>#include<vector>using namespace std;const int maxn = 110;const int inf = 1e9;int n , m;int p[maxn];int maxcost[maxn][maxn];bool vis[maxn];bool sel[maxn*maxn];int find(int x){if (x==p[x]) return x;return p[x] = find(p[x]);}struct Edge{Edge(int uu=0,int vv=0,int ww=0) : u(uu) , v(vv) , w(ww) { }int u , v , w;}edge[maxn*maxn];inline bool operator < (const Edge &e1,const Edge &e2){return e1.w < e2.w;}vector<Edge> G[maxn];inline int max(int a,int b) { return a < b ? b : a; }void input(){int u ,v , w;for (int i = 0 ; i < m ; ++i){scanf("%d%d%d",&u,&v,&w);edge[i] = Edge(u,v,w);}sort(edge,edge+m);}void dfs(int s,int x,int maxc){if (vis[x]) return;vis[x] = true;if (maxcost[s][x] < maxc) maxcost[s][x] = maxc;for (int i = 0 ; i < G[x].size() ; ++i){int y = G[x][i].v;dfs(s,y,max(maxc,G[x][i].w));}}void solve(){for (int i = 1 ; i <= n ; ++i) p[i] = i , G[i].clear();int u , v , w;int S1 = 0 , S2 = inf;for (int i = 0 ; i < m ; ++i){sel[i] = false;u = find(edge[i].u);v = find(edge[i].v);if (u==v) continue;sel[i] = true;p[u] = v;u = edge[i].u , v = edge[i].v;w = edge[i].w;G[u].push_back(Edge(u,v,w));G[v].push_back(Edge(v,u,w));S1 += w;}memset(maxcost,-1,sizeof(maxcost));printf("%d ",S1);for (int i = 1 ; i <= n ; ++i) { memset(vis,false,sizeof(vis)); dfs(i,i,-1); }for (int i = 0 ; i < m ; ++i) if (!sel[i])S2 = min(S2,S1+edge[i].w-maxcost[edge[i].u][edge[i].v]);printf("%d\n",S2);}int main(){int T; cin>>T;while (T--){scanf("%d%d",&n,&m);input();solve();}}
0 0
原创粉丝点击