WEEK 6 C Master of Magic I

topic:

Dongdong is bored in his hometown and wants to farm. There are n blocks of farmland, numbered from 1 to n. Farming
is a must. It is well known that Dongdong is a magician. He can consume a certain amount of MP to cast magic on a field, making the water of the Yellow River come to the sky. He can also consume a certain amount of MP to build a portal on the canals of two fields, so that this field references the water of the field with water. (1 <= n <= 3e2)
The water consumption in the sky of the Yellow River is Wi, i is the farmland number (1 <= Wi <= 1e5)
. The consumption for establishing the portal is Pij, and i and j are the farmland numbers (1 <= Pij <= 1e5, Pij = Pji, Pii = 0)
Dongdong is the minimum consumption of all field irrigation

Input

Line 1: a number n,
line 2 to line n + 1: line wi,
line n + 2 to line 2n + 1: matrix is ​​the pij matrix

Output

Dong Dong's minimum MP value

Example Input

4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0

Output

9

Ideas:

Considering each farmland as a point, diversion will connect the two points between the two points. The MP consumption of the diversion between the two points can be regarded as the weight of this side, so that the entire farmland becomes a weighted graph. We see sky as a super origin, which also has weighted edges to various points in the farmland. In this way, the problem can be transformed into the problem of graph reconstruction, that is, to find the minimum spanning tree in a weighted graph.
The Kruskal algorithm is used here, and all edges are sorted in ascending order according to the weights, and all edges are traversed using the check set. If the edges have endpoints that are not in the same set, the set of the two points is merged, and the edge is selected until it is selected n edges (with n + 1 points), these selected edges can constitute the minimum spanning tree of the weighted graph, and the sum of their weights is the answer.

Code:

#include <iostream>
#include <algorithm>

using namespace std;

#define rep(i,s,t)for(int i=s;i<=t;i++)

const int maxn = 3e2 + 10;
int par[maxn];
int n, tot;

struct edge
{
	int u, v, w;
	bool operator<(const edge &e)const
	{
		return w < e.w;
	}
}es[maxn*maxn];

void init(int n)
{
	for (int i = 0; i <= n; i++)
		par[i] = i;
}
int find(int x)
{
	if (par[x] == x)
		return x;
	else
		return par[x] = find(par[x]);
}
bool unite(int x, int y)
{
	x = find(x), y = find(y);
	if (x == y)
		return false;
	par[x] = y;
	return true;
}

int kruskal()
{
	init(n);
	sort(es, es + tot);
	int cnt = 0, ans = 0;
	rep(i, 0, tot - 1)if (unite(es[i].u, es[i].v))
	{
		ans += es[i].w;
		if (++cnt == n)
			return ans;
	}
	return -1;
}

int main()
{
	tot = 0;
	scanf_s("%d", &n);
	rep(i, 1, n)scanf_s("%d", &es[tot].w), es[tot].u = 0, es[tot].v = i, tot++;
	rep(i, 1, n)rep(j, 1, n)
	{
		scanf_s("%d", &es[tot].w);
		if (i == j)
			continue;
		es[tot].u = i, es[tot].v = j, tot++;
	}
	printf("%d", kruskal());
	return 0;
}
Published 32 original articles · praised 0 · visits 679

Guess you like

Origin blog.csdn.net/qq_43814559/article/details/105253982