题目链接
prim算法
//
// Created by chaomaer on 2017/10/27.
//
#include <stdio.h>
#include <string.h>
const int N = 2001;
int map[N][N];
int v;
char name[N][8];
bool flag[N];
void fillmap() {
for (int i = 0; i < v; ++i) {
for (int j = 0; j < v; ++j) {
int sum = 0;
for (int k = 0; k < 7; ++k) {
if (name[i][k] != name[j][k]) sum++;
}
map[i][j] = map[j][i] = sum;
}
}
}
int prim() {
// 首先将第一个元素放到访问集合中
int *dis = new int[v];
int res = 0;
flag[0] = true;
for (int i = 1; i < v; ++i) {
dis[i] = map[i][0];
}
for (int i = 1; i < v; ++i) {
// 找到最小的一个割边值
int min = 0xfffffff;
int index = -1;
for (int j = 1; j <v; ++j) {
if (flag[j]) continue;
if (min > dis[j]){
min = dis[j];
index = j;
}
}
res += min;
// 更新dis的值
flag[index] = true;
for (int j = 1; j < v ; ++j) {
if (flag[j]) continue;
if (dis[j]>map[j][index]) dis[j] = map[j][index];
}
}
delete dis;
return res;
}
int main() {
while (scanf("%d", &v) && v) {
memset(flag, false, sizeof(flag));
for (int i = 0; i < v; ++i) {
scanf("%s", name[i]);
}
fillmap();
int res = prim();
printf("The highest possible quality is 1/%d.\n", res);
}
}
kruskal算法
#include<iostream>
#include<vector>
#include <stdio.h>
#include<algorithm>
int v;
int const N = 2001;
using namespace std;
int father[N];
char name[N][8];
struct Node{
int a;
int b;
int w;
Node(int aa,int bb,int cc){
a = aa;b = bb;w = cc;
}
};
vector<Node> vctnode;
void initset(){
for (int i = 0; i < v; ++i) {
father[i] = i;
}
}
int root(int a){
return a==father[a]?a:father[a]=root(father[a]);
}
void connect(int a,int b){
int a1 = root(a);
int a2 = root(b);
father[a1] = a2;
}
void fillvetnode(){
for (int i = 0; i < v; ++i) {
for (int j = i+1; j < v; ++j) {
int sum = 0;
for (int k = 0; k < 7; ++k) {
if (name[i][k] != name[j][k])
sum++;
}
vctnode.push_back(Node(i,j,sum));
}
}
}
bool cmp(const Node &a, const Node &b){
return a.w<b.w;
}
int kruskal(){
int sum = 0;
int ans = 0;
for (int i = 0; i < vctnode.size(); ++i) {
Node tem = vctnode[i];
int a = tem.a;
int b = tem.b;
if (root(a) != root(b)){
connect(a,b);
sum++;
ans += tem.w;
if (sum == v-1) break;
}
}
return ans;
}
int main(){
while (scanf("%d", &v)&&v){
vctnode.clear();
initset();
for (int i = 0; i < v; ++i) {
scanf("%s",name[i]);
}
fillvetnode();
sort(vctnode.begin(), vctnode.end(), cmp);
int res = kruskal();
printf("The highest possible quality is 1/%d.\n",res);
break;
}
}
本次练习+算法导论让我对最小生成树有了更直观的理解,感谢poj,感谢CLRS.