您的位置:首页 > 其它

最小生成树 Kruskal和Prim算法

2010-05-05 17:49 645 查看
农场铺网络问题

Sample Input

4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0

Sample Output

28

Kruskal算法解答:
#include <iostream>
#include <algorithm>
using namespace std;

typedef struct Edge{
int x, y, dis;
};
Edge town[10002];    //存放边的两端和长度信息
bool flag[102];        //标记新的结点是否加入
int nodeSet[102];    //标记编号对应的结点所属的集合

bool compare(Edge a, Edge b)
{
return (a.dis < b.dis);
}

int main()
{
int n, nodeTag;
while(cin>>n){
nodeTag = 1;
for(int i = 1; i <= n; i++){
nodeSet[i] = i;    //结点所在的set即为其编号
for(int j = 1; j <= n; j++){
scanf("%d", &town[nodeTag].dis);
town[nodeTag].x = i;
town[nodeTag].y = j;
nodeTag++;
}
}
sort(town+1, town+nodeTag, compare);
nodeTag = n+1;    //去掉前面的n个0,从最小的边开始
int sum = 0, edgeSet = 0;
while(edgeSet < n-1){//n-1条边时完全所有结点的连接,访问过的结点都会加入到一个set中
if((!flag[town[nodeTag].x]) && (flag[town[nodeTag].y])){
sum += town[nodeTag].dis;
edgeSet++;
flag[town[nodeTag].x] = true;
nodeSet[town[nodeTag].x] = nodeSet[town[nodeTag].y];
}else if((flag[town[nodeTag].x]) && (!flag[town[nodeTag].y])){
sum += town[nodeTag].dis;
edgeSet++;
flag[town[nodeTag].y] = true;
nodeSet[town[nodeTag].y] = nodeSet[town[nodeTag].x];
}else if((!flag[town[nodeTag].x]) && (!flag[town[nodeTag].y])){
sum += town[nodeTag].dis;
edgeSet++;
flag[town[nodeTag].x] = true;
flag[town[nodeTag].y] = true;
nodeSet[town[nodeTag].x] = nodeSet[town[nodeTag].y];
}else {    //两端顶点都加入了set,判断新加入的边是否使结点形成了环
if(nodeSet[town[nodeTag].x] != nodeSet[town[nodeTag].y]){
sum += town[nodeTag].dis;
edgeSet++;
int tmp = nodeSet[town[nodeTag].y];
for(int i = 1; i <= n; i++)    //将两个set中的元素合到一个set中
if(nodeSet[i] == tmp)
nodeSet[i] = nodeSet[town[nodeTag].x];
}
}
nodeTag ++;
}
cout<<sum<<endl;
memset(flag, 0, sizeof(flag));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: