您的位置:首页 > 其它

Network POJ 1861 ZOJ 1542 Kruskal算法 提问方式有点变化而已

2013-03-31 01:34 405 查看
和ZOJ 1203解法一样,不赘述,我都直接复制的代码修改了一下

贴代码:

View Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define MAXN  1020
#define MAXM 15020
using namespace std;
int n,m;  //n为顶点个数,m为边数
struct ArcNode
{
int u,v;  //一条边的起点和终点
int w;  //边的权值
bool operator <(const ArcNode & other) const
{
if(w < other.w) return true;
else return false;
};
} edge[MAXM];  //存边
int parent[MAXN];  //用于并查集
int l[MAXN];
int Find(int x)
{
int s;
for(s = x; parent[s] >= 0; s = parent[s]);
while(s != x)
{
int temp = parent[x];
parent[x] = s;
x = temp;
}
return s;
}
void Union(int x,int y)
{
int r1 = Find(x);
int r2 = Find(y);
int temp = parent[r1] +parent[r2];//两根结点所带结点的总数
if(parent[r1] > parent[r2])
{
parent[r1] = r2;
parent[r2] = temp;
}
else
{
parent[r2] = r1;
parent[r1] = temp;
}
}
void Kruskal()
{
int i;
for(i=1; i <= n; i++)
parent[i] = -1;
int num =0;
sort(edge,edge+m);
for(i=0; i<m; i++)
{
int u = edge[i].u;
int v = edge[i].v;
if(Find(u) != Find(v))
{
Union(u,v);
l[num++] = i;
}
if(num >= n-1) break;
}
}
int main()
{
//    freopen("in.cpp","r",stdin);
int i;
while(~scanf("%d%d",&n,&m))
{
for(i=0; i<m; i++)
{
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
}
Kruskal();
printf("%d\n%d\n",edge[l[n-2]].w,n-1);
for(i =0; i<n-1; i++)
printf("%d %d\n",edge[l[i]].u,edge[l[i]].v);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: