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.
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.
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.
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.
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.
题意:现在要修一些路,以便所有的村庄都可以相通,不一定连个村庄有一条路才算相同,也可以通过其他村庄来使这两个村庄相通。现在要用最少的钱来使各个村庄相同,求至少要花多少钱。
解题思路:运用prim算法,dis[i]保存i村庄修路到某一村庄最少的钱。将已经相通的村庄记vis[i]=1,未相通的村庄记vis[i]=0。每次修路都修从vis[i]=1的村庄到vis[i]=0中dis[i]最小的的村庄的路,直到所有的村转都相通。然后每修一次路后,都要更新一下dis[i]。
#include <iostream>
#include<stdio.h>
using namespace std;
int map[105][105],dis[105],vis[105],n,ans;
void prim()
{
for (int i = 1; i <= n; i++)
{
dis[i] = map[1][i];
vis[i] = 0;
}
dis[1] = 0;
vis[1] = 1;
for (int i = 1; i <= n; i++)
{
int minn = 99999,x;
for(int j=1;j<=n;j++)
if (dis[j] < minn && !vis[j])
{
minn = dis[j];
x = j;
}
if (minn == 99999)
break;
vis[x] = 1;
ans = ans + minn;
for (int j = 1; j <= n; j++)//更新dis[i]
if (!vis[j] && dis[j] > map[x][j])
dis[j] = map[x][j];
}
}
int main()
{
while (cin >> n)
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> map[i][j];
int a;
int b, c;
cin >> c;
for (int i = 0; i < c; i++)
{
cin >> a >> b;//将已经修了的路的权值记为0,所以肯定会免费修这些路先。
map[a][b] = 0;
map[b][a] = 0;
}
ans = 0;
prim();
cout << ans << endl;
}
}