POJ 2421

#include<iostream>
#include<queue>
#include<stdio.h>
#define ll long long
using namespace std;
const int maxn = 111;
int a[maxn][maxn];
int dis[maxn];
int n, m, x, y;
void prim() {
	int i, j, k, mina;
	bool f[maxn];
	for (i = 2;i <= n;++i) {
		f[i] = 0;
		dis[i] = a[1][i];
	}
	dis[1] = 0;
	f[1] = 1;
	for (i = 1;i <= n - 1;++i) {
		mina = 9999999;
		k = 0;
		for (j = 1;j <= n;++j) {
			if (!f[j] && dis[j] < mina) {
				mina = dis[j];
				k = j;
			}
		}
		if (k == 0) return;
		f[k] = 1;
		for (j = 1;j <= n;++j) {
			if (!f[j] && a[k][j] != 9999999 && dis[j] > a[k][j]) {
				dis[j] = a[k][j];
			}
		}
	}
}
int main() {
	while (cin>>n) {
		for (int i = 1;i <= n;++i)
			for (int j = 1;j <= n;++j)
				cin>>a[i][j];
		cin>>m;
		while (m--) {
			cin>>x>>y;
			a[x][y] = a[y][x] = 0;
		}
		prim();
		int ans = 0;
		for (int i = 1;i <= n;++i)
			ans += dis[i];
		cout<<ans<<endl;
	}
}

最小生成树,就是一开始有一些联通了, 所以要在标记数组里面进行标记,然后再从没标记的里面继续挑选最短的修路+标记,直到所有都标记了就可以了,没什么坑难点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值