您的位置:首页 > 其它

poj1861 network(并查集+kruskal最小生成树

2015-08-20 14:50 489 查看
题目地址:http://poj.org/problem?id=1861

题意:输入点数n和边数n,m组边(点a,点b,a到b的权值)。要求单条边权值的最大值最小,其他无所谓(所以多解:(。输出单条边最大值,边的数量,每条边(点a,点b)。

思路:结构体记录节点x,y和权值d。写一个比较函数+sort使结构体按权值由小到大排序。

并查集:两个集合被选中的和没被选中的。

kruskal:初始化每个节点独自一个集合,每次输入不在一个集合的就合并并记录,在一个集合的不管。输出记录数组最后一个节点的权值(edge[c-1].d),记录数组大小(c-1),每条边(从1到c-1)【kruskal函数最后一次多了一个c++,脚标又是从1开始。

#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 15000+5;

struct bian
{
int x, y, d;
}edge
, ans
;

int fa
, c = 1, n, m;

int cmp(bian a, bian b)
{
return a.d < b.d;
}

void init(int n)
{
for(int i = 1; i <= n; i++)
fa[i] = i;
}

int found(int x)
{
if(fa[x] == x)
return x;
else
fa[x] = found(fa[x]);
return fa[x];
}

void unite(int x, int y)
{
int px = found(x);
int py = found(y);
if(px == py)
return;
fa[py] = px;
}

void kruskal()
{
for(int i = 1; i <= m; i++)
{
int x = edge[i].x;
int y = edge[i].y;
if(found(x) != found(y))//两顶点不在一个集合则把该边放入
{
unite(x, y);
ans[c].x = x;
ans[c].y = y;
ans[c].d = edge[i].d;
c++;
}
}
}

int main()
{
scanf("%d%d", &n, &m);//n个点,m条边
init(n);
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].d);
}
sort(edge+1, edge+m+1, cmp);//sort函数是从0到n-1的!!!!!!!!!!!!!!!
kruskal();
printf("%d\n", ans[c-1].d);
printf("%d\n", c-1);
for(int i = 1; i < c; i++)
{
printf("%d %d\n", ans[i].x, ans[i].y);
}
return 0;
}


【玛德!!!!!!!!!!!sort默认从0到n-1!!!!!!!!!!要是脚标从1开始记得改成sort(a+1, a+n+1)!!!!!!!!!!!】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: