最小生成树kruskal算法
#include<cstdio> #include<algorithm> #include <iostream> using namespace std; const int maxn = 2000+10; char map[maxn][10]; int f[maxn]; int n,cnt; struct edge{ int u,v; int w; }e[maxn*maxn/2]; int dist(int st, int en) { int distance = 0; for(int i = 0; i < 7; i++) if(map[st][i] != map[en][i]) distance++; return distance; } bool cmp(edge a, edge b) { return a.w < b.w; } int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); } int Kruskal() { int ans = 0; for(int i = 1; i <= n; i++) f[i] = i; sort(e,e+cnt,cmp); for(int i = 0; i < cnt; i++) { int u = find(e[i].u); int v = find(e[i].v); if(u != v) { f[v] = u; ans += e[i].w; } } return ans; } int main() { while(scanf("%d", &n) != EOF) { if(n == 0) break; for(int i = 1; i <= n; i++) scanf("%s", map[i]); cnt = 0; for(int i = 1; i < n; i++) { for(int j = i+1; j <= n; j++) { e[cnt].u = i; e[cnt].v = j; e[cnt].w = dist(i,j); //把字符串差值变权值 cnt++; } } int ans = Kruskal(); printf("The highest possible quality is 1/%d.\n", ans); } return 0; }
dist为处理权值的函数,也可以把判断的连通问题写进merge函数,并查集压缩路径,用来提高效率