poj-2421 Constructing Roads *

/*
* 蛮水的一道MST Kruskal, 链表实现
*
* 预处理:
* 根据已有的边,把相应的集合合并。。再Kruskal
*
* 另一种方法:
* 把已有边的权值改为0
*
*/
#include
<cstdio>
#include
<algorithm>
using namespace std;

const int maxN = 100 + 5;
int n, totEdgeNum, G[maxN][maxN], q, ans;

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

struct SNode{
int num, len;
SNode
*rep, *next;
};
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;
x
->len = 1;

return x;
}
SNode
* findSet(SNode *x){
return x->rep;
}
SNode
* unionSet(SNode *lhs, SNode *rhs){
SNode
*first, *second, *cur;
if(lhs->rep->len >= rhs->rep->len){
first
= lhs->rep; second = rhs->rep;
}
else{
first
= rhs->rep; second = lhs->rep;
}

cur
= second;
while(cur != NULL){
cur
->rep = first;
cur
= cur->next;
}
tail[first
->num]->next = head[second->num];
tail[first
->num] = tail[second->num];
head[second
->num] = head[first->num];

return first;
}

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

void mstKruskal(){
qsort(edge, totEdgeNum,
sizeof(SEdge), cmp);

/*
for(int i=0; i<totEdgeNum; i++){
printf("%d ", edge[i].w);
}
printf("\n");
*/


for(int i=0; i<totEdgeNum; i++){
if(findSet(node[edge[i].u]) != findSet(node[edge[i].v])){
ans
+= edge[i].w;
unionSet(node[edge[i].u], node[edge[i].v]);
}
}
}




int main(){
//图输入
scanf("%d", &n);
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
scanf(
"%d", &G[i][j]);
}
}

totEdgeNum
= 0;
for(int i=0; i<n; i++){
for(int j=0; j<=i; j++){
edge[totEdgeNum].u
= i;
edge[totEdgeNum].v
= j;
edge[totEdgeNum].w
= G[i][j];
totEdgeNum
++;
}
}


//初始化
for(int i=0; i<n; i++){
node[i]
= new SNode;
node[i]
->num = i;
makeSet(node[i]);
}
scanf(
"%d", &q);
int u, v;
for(int i=0; i<q; i++){
scanf(
"%d%d", &u, &v);
if(node[u-1]->rep != node[v-1]->rep)
unionSet(node[u
-1], node[v-1]);
}


//kruskal
mstKruskal();

printf(
"%d\n", ans);


return 0;
}

posted on 2011-09-02 10:16  龙豆  阅读(259)  评论(0编辑  收藏  举报

导航