题意:省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
题解:最小生成树
将已修通的路的成本置为0即可。
这里采用pirm算法。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
const int maxn = 1e2 + 10;
int n, mst[maxn], m;
int edge[maxn][maxn], lowcost[maxn];
int prim() {
int i, j, minid;
int sum = 0, min;
for (i = 2; i <= n; i++) {
lowcost[i] = edge[1][i];
mst[i] = 1;
}
mst[1] = 0;
for (i = 2; i <= n; i++) {
min = 0x3f3f3f3f;
minid = 0;
for (j = 1; j <= n; j++) {
if (lowcost[j] < min && mst[j] != 0) {
min = lowcost[j];
minid = j;
}
}
sum += min;
mst[minid] = 0;
for (j = 1; j <= n; j++) {
if (edge[minid][j] < lowcost[j] && mst[j] != 0) {
lowcost[j] = edge[minid][j];
}
}
}
return sum;
}
int u, v, w, f;
int main() {
while (~scanf("%d", &n) && n) {
m = (n - 1) * n / 2;
memset(edge, 0x3f, sizeof(edge));
for (int i = 1; i <= m; i++) {
scanf("%d%d%d%d", &u, &v, &w, &f);
edge[u][u] = edge[v][v] = 0;
if (f) edge[u][v] = edge[v][u] = 0;
else edge[u][v] = edge[v][u] = w;
}
printf("%d\n", prim());
}
return 0;
}