ACM Contest and Blackout UVA - 10600 次小生成树(kruskal算法)

  • ACM Contest and Blackout

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1541

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

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

题意:求最小生成树和次小生成树的权值。注意次小生成树和最小生成树权值可能相同。

思路:次小生成树模板题。用二维数组maxd优化,求出次小生成树。

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 7;
int n, m;
struct edge {
	int u, v;
	int cost, used;
}e[MAXN];
int pre[MAXN];
int maxd[1010][1010];
vector<int>G[1010];
bool cmp(edge a, edge b);
int find(int x);
void Union(int a, int b);
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int sum = 0;
		scanf("%d%d", &n, &m);
		memset(maxd, 0, sizeof(maxd));
		for (int i = 0; i <= n; ++i) {
			pre[i] = i;
			G[i].clear();
			G[i].push_back(i);
		}
		for (int i = 1; i <= m; ++i) {
			scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].cost);
			e[i].used = 0;
		}
		sort(e + 1, e + 1 + m, cmp);
		for (int i = 1; i <= m; ++i) {
			int u = find(e[i].u), v = find(e[i].v);
			int cost = e[i].cost;
			if (u != v) {
				sum += e[i].cost;
				e[i].used = 1;
				for (int k = 0; k<G[u].size(); ++k) {
					for (int j = 0; j<G[v].size(); ++j) {
						maxd[G[u][k]][G[v][j]] = maxd[G[v][j]][G[u][k]] = cost;
					}
				}
				Union(u, v);
				for (int k = 0; k<G[u].size(); ++k) {
					G[v].push_back(G[u][k]);
				}
			}
		}
		int ans = INF;
		for (int i = 1; i <= m; ++i) {
			if (!e[i].used) {
				ans = min(ans, sum + e[i].cost - maxd[e[i].u][e[i].v]);
			}
		}
		printf("%d %d\n", sum, ans);
	}
	return 0;
}

bool cmp(edge a, edge b) {
	return a.cost<b.cost;
}

int find(int x) {
	if (pre[x] == x)
		return x;
	return pre[x] = find(pre[x]);
}

void Union(int a, int b) {
	int x = find(a);
	int y = find(b);
	if (x == y)
		return;
	pre[x] = y;
}

相似题型:UVA - 10462 

猜你喜欢

转载自blog.csdn.net/weixin_43821265/article/details/87932795