poj-1789 Truck History *

/*
* 很直接的最小生成树
*
* 版本一: Kruskal, 链表实现
*
*/

#include
<cstdio>
#include
<algorithm>
using namespace std;

const int maxN = 2000 + 5;
const int letterNum = 7;
int n, totEdgeNum, ans;
char code[maxN][letterNum + 2];

struct SEdge{ //
int w, u, v;
};
SEdge edge[maxN
* maxN];

struct SNode{ //链表的节点
SNode *rep, *next;
int num;
};
SNode
*head[maxN], *tail[maxN], *node[maxN];

SNode
*makeSet(SNode *x){
head[x
->num] = x;
tail[x
->num] = x;
x
->rep = x; x->next = NULL;

return x;
}
SNode
*findSet(SNode *x){
return x->rep;
}
//直接把 rhs 连在 lhs 后面
SNode *unionSet(SNode *lhs, SNode *rhs){
SNode
*lhsRep = findSet(lhs);
SNode
*rhsRep = findSet(rhs);

tail[lhsRep
->num]->next = rhsRep;
SNode
*tmpNode = rhsRep;
while(tmpNode != NULL){
tmpNode
->rep = lhsRep;
tmpNode
= tmpNode->next;
}

tail[lhsRep
->num] = tail[rhsRep->num];
head[rhsRep
->num] = head[lhsRep->num];

return lhsRep;
}

int cmp(const void *lhs, const void *rhs){
SEdge
*a = (SEdge *)lhs; SEdge *b = (SEdge *)rhs;
return a->w - b->w;
}

void mstKruskal(){
//初始化
for(int i=0; i<n; i++){
node[i]
= new SNode;
node[i]
->num = i;
makeSet(node[i]);
}
//边按权值排序
qsort(edge, totEdgeNum, sizeof(SEdge), cmp);

for(int i=0; i<totEdgeNum; i++){
SNode
*uRep = findSet(node[edge[i].u]);
SNode
*vRep = findSet(node[edge[i].v]);

if(uRep != vRep){
unionSet(uRep, vRep);
ans
+= edge[i].w;
}
}

}

//计算边的权值
int inline getDistance(char *lhs, char *rhs){
int dis = 0;
for(int i=0; i<letterNum; i++)
if(lhs[i] != rhs[i]) dis++;
return dis;
}


int main(){
while(scanf("%d", &n)){
if(n == 0) return 0;

ans
= totEdgeNum = 0;
getchar();
for(int i=0; i<n; i++){
gets(code[i]);
for(int j=0; j<=i; j++){
edge[totEdgeNum].w
= getDistance(code[i], code[j]);
edge[totEdgeNum].u
= i; edge[totEdgeNum].v = j;
totEdgeNum
++;
}
}

mstKruskal();

printf(
"The highest possible quality is 1/%d.\n", ans);

}



return 0;
}

--

/*
* 很直接的最小生成树
*
* 版本二: Kruskal, 不相交集合森林
*
*/

#include
<cstdio>
#include
<algorithm>
using namespace std;

const int maxN = 2000 + 5;
const int letterNum = 7;
int n, totEdgeNum, ans;
char code[maxN][letterNum + 2];

struct SEdge{ //
int w, u, v;
};
SEdge edge[maxN
* maxN];

struct SNode{ //链表的节点
SNode *p;
int num, rank;
};
SNode
*node[maxN];

SNode
*makeSet(SNode *x){
x
->p = x;
x
->rank = 0;

return x;
}
SNode
*findSet(SNode *x){
if(x != x->p)
x
->p = findSet(x->p); //路径压缩
return x->p;
}
void link(SNode *lhs, SNode *rhs){
if(lhs->rank > rhs->rank) //按秩合并
rhs->p = lhs;
else{
lhs
->p = rhs;
if(lhs->rank == rhs->rank)
rhs
->rank++;
}
}
void unionSet(SNode *lhs, SNode *rhs){
link(findSet(lhs), findSet(rhs));
}


int cmp(const void *lhs, const void *rhs){
SEdge
*a = (SEdge *)lhs; SEdge *b = (SEdge *)rhs;
return a->w - b->w;
}

void mstKruskal(){
//初始化
for(int i=0; i<n; i++){
node[i]
= new SNode;
node[i]
->num = i;
makeSet(node[i]);
}
//边按权值排序
qsort(edge, totEdgeNum, sizeof(SEdge), cmp);

for(int i=0; i<totEdgeNum; i++){
SNode
*uRep = findSet(node[edge[i].u]);
SNode
*vRep = findSet(node[edge[i].v]);

if(uRep != vRep){
unionSet(uRep, vRep);
ans
+= edge[i].w;
}
}

}

//计算边的权值
int inline getDistance(char *lhs, char *rhs){
int dis = 0;
for(int i=0; i<letterNum; i++)
if(lhs[i] != rhs[i]) dis++;
return dis;
}


int main(){
while(scanf("%d", &n)){
if(n == 0) return 0;

ans
= totEdgeNum = 0;
getchar();
for(int i=0; i<n; i++){
gets(code[i]);
for(int j=0; j<=i; j++){
edge[totEdgeNum].w
= getDistance(code[i], code[j]);
edge[totEdgeNum].u
= i; edge[totEdgeNum].v = j;
totEdgeNum
++;
}
}

mstKruskal();

printf(
"The highest possible quality is 1/%d.\n", ans);

}



return 0;
}

你可能感兴趣的:(history)