题意:将n个村庄连接起来,每两个村庄之间连接的消耗已经知道。求将所有村庄连在一起所需要的最小消耗。
题解:给出两组代码。
Prim:
#include<cstdio>
#define MAX 300
#define INF 99999999
int map[MAX][MAX];
int dis[MAX], vis[MAX];
int Prim ( int n )
{
int i, j, k, m, sum = 0;
for ( i = 0; i < n; i++ )
dis[i] = INF, vis[i] = 0;
sum = dis[0] = 0;
for ( i = 0; i < n; i++ )
{
for ( m = INF, j = 0; j < n; j++ )
if ( !vis[j] && dis[j] < m )
m = dis[k=j];
vis[k] = 1;
sum += m;
for ( j = 0; j < n; j++ )
if ( !vis[j] && map[k][j] < dis[j] )
dis[j] = map[k][j];
}
return sum;
}
int main()
{
int n;
while ( scanf("%d",&n) != EOF )
{
for ( int i = 0; i < n; i++ )
for ( int j = 0; j < n; j++ )
scanf("%d",&map[i][j]);
printf("%d\n",Prim(n));
}
return 0;
}
#include <iostream>
using namespace std;
int father[101], n;
struct edge
{
int u,v,w;
} e[101*101/2];
int cmp(const void *a, const void *b)
{
return (*(edge *)a).w - (*(edge *)b).w;
}
int find_set ( int x )
{
if ( x != father[x] )
father[x] = find_set(father[x]);
return father[x];
}
int Kruskal ( int x )
{
int i, sum = 0;
for ( i = 0; i < n; i++ )
father[i] = i;
qsort(e,x,sizeof(edge),cmp);
for ( i = 0; i < x; i++ )
{
int a = find_set(e[i].u);
int b = find_set(e[i].v);
if ( a != b )
{
father[b] = a;
sum += e[i].w;
}
}
return sum;
}
int main()
{
while ( cin >> n )
{
int c = 0, temp;
for ( int i = 0; i < n; i++ )
for ( int j = 0; j < n; j++ )
{
cin >> temp;
if ( i < j )
{
e[c].u = i;
e[c].v = j;
e[c].w = temp;
c++;
}
}
cout << Kruskal(c) << endl;
}
return 0;
}