| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
Kruskal模板算法,贴代码,飘过~#include <iostream>
#include <algorithm>
#define MAX 55
using namespace std;
int father[MAX]; //记录各节点的父节点
int m[MAX][MAX]; //存储采用所用线缆后的图的邻接表
int cmax;
struct edge
{
int x,y;
int w;
}e[MAX * MAX / 2]; //用来存储各个边的信息,x点至y点的权值为w
int find_set(int a) //查找a所在的集合,回溯时顺便压缩路径
{
if(a != father[a])
{
father[a] = find_set(father[a]);
}
return father[a];
}
void Union(int x,int y,int w) //合并x和y所在的集合,并用cmax记录所有边的权值之和
{
if(x == y) return;
father[y] = x;
cmax += w;
}
bool cmp(edge a,edge b) //非降序排序排序函数
{
return a.w < b.w;
}
int main()
{
int n,r,i,j,s,t,tmp,k;
while(scanf("%d%d",&n,&r) != EOF && n!= 0)
{
k = 0;
cmax = 0;
memset(m,-1,sizeof(m)); //初始化数组
if(r == 0) //如果r == 0,直接下次循环
{
cout << 0 << endl;
continue;
}
for(i = 0;i < r;i++)
{
cin >> s >> t >> tmp; //输入线缆的数据,连接s和t权值为tmp的线缆
if(s > t) //只对m的上三角信息进行存储
{
int temp = s;
s = t;
t = temp;
}
if(m[s-1][t-1] == -1 || m[s-1][t-1] > tmp) m[s-1][t-1] = tmp; //只保留连接两点的线缆长度最短的边
}
//Kruskal算法
for(i = 0;i < n;i++)
{
father[i] = i;
for(j = 0;j < n;j++)
{
if(i < j )
if(m[i][j] != -1)
{
e[k].x = i;
e[k].y = j;
e[k].w = m[i][j];
k++;
}
}
}
sort(e,e + k,cmp);
for(i = 0;i < k;i++)
{
Union(find_set(e[i].x),find_set(e[i].y),e[i].w);
}
cout << cmax << endl;
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator