2421:Constructing Roads【最小生成树】:非连通图求最小生成树

在n个村庄之间修路使所有村庄连通 其中有些路已经修好了 求至少还需要修多长路

还是裸的最小生成树 我使用了克鲁斯卡尔算法,当拿出来一个边的两个端点已经是一个集合中就continue,

#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<string>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;

#define ll int
#define MAX 105
#define inf 0x3FFFFFFF

ll d[MAX][MAX], kind[MAX];

struct edge {
	ll from, to, cost;
	edge(ll a = 0, ll b = 0, ll c = 0) { from = a, to = b, cost = c; }
};

vector<edge> e;

bool cmp(edge e1, edge e2) {
	return e1.cost < e2.cost;
}

ll find(ll k) {
	if (k == kind[k]) return k;
	else return kind[k] = find(kind[k]);
}

void unite(ll a, ll b) {
	kind[find(b)] = kind[find(a)];
}

int main() {
	ll N, Q, a, b; scanf("%d", &N);
	for (int i = 1; i <= N; i++)kind[i] = i;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			scanf("%d", &d[i][j]);
			if (j > i)e.push_back(edge(i, j, d[i][j]));
		}
	}
	scanf("%d", &Q);
	for (int i = 0; i < Q; i++) {
		scanf("%d%d", &a, &b);
		unite(a, b);
	}
	sort(e.begin(), e.end(), cmp);
	ll res = 0;
	for (int i = 0; i < e.size(); i++) {
		edge t = e[i];
		if (find(t.from) == find(t.to))continue;
		res += t.cost; unite(t.from, t.to);
	}
	printf("%d", res);
}
发布了269 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/csyifanZhang/article/details/105602984