題目鏈接:POJ 2421 Constructing Roads 修建道路
Constructing Roads Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 19698 Accepted: 8221
Description
There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.Input
The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.Output
You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.Sample Input
3 0 990 692 990 0 179 692 179 0 1 1 2
Sample Output
179
Source
PKU Monthly,kicc題意:
有N個村莊,編號從1到N。現需要在這N個村莊之間修路,使得任何兩個村莊之間都可以連通。稱A、B兩個村莊是連通的,當且僅當A與B有路直接連接,或者存在村莊C,使得A和C兩村莊之間有路連接,且C和B之間有路連接。已知某些村莊之間已經有路直接連接了,試修建一些路使得所有村莊都是連通的、且修路總長度最短。
分析:
最小生成樹問題,已經修好路的村莊之間將他們的長度置為0,然後再用Kruskal算法求解。
代碼:
#include#include #include #include using namespace std; #define maxn 110 #define maxm 5050 int parent[maxn]; int g[maxn][maxn]; int m, ans; struct edge { int u, v, w; }EG[maxm]; bool cmp(edge a, edge b) { return a.w < b.w; } int Find(int x) { if(parent[x] == -1) return x; return Find(parent[x]); } void Kruskal() { memset(parent, -1, sizeof(parent)); ans = 0; sort(EG, EG+m, cmp); for(int i = 0; i < m; i++) { int t1 = Find(EG[i].u), t2 = Find(EG[i].v); if(t1 != t2) { ans += EG[i].w; parent[t1] = t2; } } } int main() { int n, q, a, b; while(~scanf("%d", &n)) { for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) scanf("%d", &g[i][j]); scanf("%d", &q); while(q--) { scanf("%d%d", &a, &b); g[a][b] = g[b][a] = 0; } m = 0; for(int i = 1; i <= n; i++) for(int j = i+1; j <= n; j++) { EG[m].u = i; EG[m].v = j; EG[m].w = g[i][j]; m++; } Kruskal(); printf("%d\n", ans); } return 0; }