链接:http://poj.org/problem?id=1258
Description
Input
Output
Sample Input
4 0 4 9 21 4 0 8 17 9 8 0 16 21 17 16 0
Sample Output
28
解题思路: 最简单的最小生成树的题目;MST-Kruscal
代码如下:(Kruscal)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <string>
#include <iomanip>
#include <cassert>
#include <algorithm>
#define LC(x) (x<<1)
#define RC(x) (LC(x)+1)
#define PI (acos(-1))
#define EPS 1e-8
#define MAXN 111111
#define MAXM 222222
#define LL long long
#define ULL unsigned long long
#define INF 0x7fffffff
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;
struct edge {
int v, u, cost;
}e[111*111];
bool cmp_e(const edge &a, const edge &b)
{
return a.cost < b.cost;
}
int ecnt, fa[111], n, v;
void addedge(int u, int v, int cost)
{
e[++ ecnt].v = v, e[ecnt].u = u, e[ecnt].cost = cost;
}
int getf(int x)
{
return fa[x] == x ? x : fa[x] = getf(fa[x]);
}
int kruscal()
{
int sum = 0;
for(int i = 1; i <= n; i ++) fa[i] = i;
sort(e + 1, e + 1 + ecnt, cmp_e);
for(int i = 1; i <= ecnt; i ++) {
int u = e[i].u, v = e[i].v;
u = getf(u), v = getf(v);
if(u == v) continue;
sum += e[i].cost;
fa[u] = v;
}
return sum;
}
int main()
{
while(scanf("%d", &n) == 1) {
ecnt = 0;
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= n; j ++) {
scanf("%d", &v);
if(v != 0) addedge(i, j, v);
}
}
printf("%d\n", kruscal());
}
return 0;
}
Prim:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 105 #define RST(N)memset(N, 0, sizeof(N)) using namespace std; int a[MAXN][MAXN], n; int flag[MAXN], tot; //flag[i]用来标记节点i是否被覆盖 void Init() { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%d", &a[i][j]); } } RST(flag), tot = 0; } int main() { while(~scanf("%d", &n)) { Init(); flag[1] = 1; //选取第一个点 for(int k=1; k<n; k++) { //循环n-1次 int min = -1, min_i; for(int i=1; i<=n; i++) { //选取下一个最小权值的节点 if(flag[i] == 0 && (min == -1 || a[1][i] < min)) { min = a[1][i]; min_i = i; } } flag[min_i]=1; //覆盖节点 for(int i=1; i<=n; i++) { //更新未覆盖节点的距离 if(flag[i] == 0 && a[1][i] > a[min_i][i]) { a[1][i] = a[min_i][i]; } } tot += a[1][min_i]; //加上权值 } printf("%d\n", tot); } return 0; }