Description:
We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.
Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.
3 0 990 692 990 0 179 692 179 0 1 1 2
179
题目大意:
有n个村庄,每个点都有自己的权值, 其中已经有给定的某几条路已经建成, 问在这些路的基础上建通所有村庄的最小花费是多少。
解题思路:
裸的最小生成树, 对于给定的两点已有的通路只要置为0即可。
代码:
#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <utility>
#include <string>
#include <cmath>
#include <vector>
#include <bitset>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
using namespace std;
/*tools:
*ios::sync_with_stdio(false);
*freopen("input.txt", "r", stdin);
*/
typedef long long ll;
typedef unsigned long long ull;
const int dir[5][2] = {0, 1, 0, -1, 1, 0, -1, 0, 0, 0};
const ll ll_inf = 0x7fffffff;
const int inf = 0x3f3f3f;
const int mod = 1000000;
const int Max = (int) 1e4;
int Map[Max][Max], vis[Max];
int n, q;
void Init() {
for (int i = 0; i < n; ++i) {
vis[i] = 0;
for (int j = 0; j < n; ++j) {
Map[i][j] = (i == j) ? 0 : inf;
}
}
}
void Prim() {
int dis[Max], ans = 0;
for (int i = 1; i <= n; ++i) {
dis[i] = Map[1][i];
}
dis[1] = 0;
for (int i = 1; i <= n; ++i) {
int Min = inf, mark;
for (int j = 1; j <= n; ++j) {
if (!vis[j] && dis[j] < Min) {
Min = dis[mark = j];
}
}
vis[mark] = 1;
ans += dis[mark];
for (int j = 1; j <= n; ++j) {
if (!vis[j] && dis[j] > Map[mark][j]) {
dis[j] = Map[mark][j];
}
}
}
printf("%d\n", ans);
}
int main() {
//freopen("input.txt", "r", stdin);
// initialization
scanf("%d", &n);
Init();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
scanf("%d", &Map[i][j]);
}
}
scanf("%d", &q);
// the road has been build
for (int i = 0; i < q; ++i) {
int a, b;
scanf("%d %d", &a, &b);
Map[a][b] = Map[b][a] = 0;
}
Prim();
return 0;
}