poj1861 kruskal

http://poj.org/problem?id=1861

#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define maxn 1001
#define maxm 15001
struct edge
{
    int u,v,w;
} edges[maxm];
int parent[maxn],ans[maxn];
int i,j,N,M;
int maxedge,num,ai;
void ufset()
{
    for(i=0; i<N; i++)
        parent[i]=-1;
}
int find(int x)
{
    int s;
    for(s=x; parent[s]>=0; s=parent[s]);
    while(s!=x)
    {
        int tmp=parent[x];
        parent[x]=s;
        x=tmp;
    }
    return s;
}
void Union(int R1,int R2)
{
    int r1=find(R1),r2=find(R2);
    int tmp=parent[r1]+parent[r2];
    if(parent[r1]>parent[r2])
    {
        parent[r1]=r2;
        parent[r2]=tmp;
    }
    else
    {
        parent[r2]=r1;
        parent[r1]=tmp;
    }
}
int cmp(const void* a,const void* b)
{
    edge aa=*(const edge*)a;
    edge bb=*(const edge*)b;
    return aa.w-bb.w;
}
void kruskal()
{
    int u,v;
    ufset();
    for(i=0; i<M; i++)
    {
        u=edges[i].u;
        v=edges[i].v;
        if(find(u)!=find(v))
        {
            ans[ai++]=i;
            if(edges[i].w>maxedge)
                maxedge=edges[i].w;
            num++;
            Union(u,v);
        }
        if(num>N-1)
            break;
    }
}
int main()
{
    //freopen("1.txt","r",stdin);
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        for(i=0; i<M; i++)
            scanf("%d%d%d",&edges[i].u,&edges[i].v,&edges[i].w);
        qsort(edges,M,sizeof(edges[0]),cmp);
        maxedge=0;  num=0;
        kruskal();
        printf("%d\n%d\n",maxedge,num);
        for(i=0; i<num; i++)
            printf("%d %d\n",edges[ans[i]].u,edges[ans[i]].v);
    }
    return 0;
}

  

时间: 2024-09-12 09:55:29

poj1861 kruskal的相关文章

图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 B(G).其中 T(G)是遍历图时所经过的边的集合,B(G) 是遍历图时未经过的边的集合.显然,G1(V, T) 是图 G 的极小连通子图,即子图G1 是连通图 G 的生成树. 深度优先生成森林   右边的是深度优先生成森林: 连通图的生成树不一定是唯一的,不同的遍历图的方法得到不同的生成树;从不

最小生成树算法:Kruskal算法的Java实现

闲来无事,写个算法,最小生成树的Kruskal算法,相对比Prim算法实现起来麻烦一点点 package trees; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.PriorityQueue; import java.util.Set; /** * 最小生成树的Kruskal算法, * For a connected weighted graph G, a s

Kruskal算法(三) Java详解

最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总和不相同的生成树. 克鲁斯卡尔算法介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路. 具体做法:首先构造一个只含n个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中,并使森林中不产生回

Kruskal算法(二) C++详解

最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总和不相同的生成树. 克鲁斯卡尔算法介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路. 具体做法:首先构造一个只含n个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中,并使森林中不产生回

Kruskal算法(一) C语言详解

最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总和不相同的生成树. 克鲁斯卡尔算法介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路. 具体做法:首先构造一个只含n个顶点的森林,然后依权值从小到大从连通网中选择边加入到森林中,并使森林中不产生回

HDU 1598 find the most comfortable road (枚举+Kruskal)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1598 题目: Problem Description XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的"舒适度"有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,fl

HDU 3938 Portal(离线+Kruskal+并查集)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3938 题目: Problem Description ZLGG found a magic theory that the bigger banana the bigger banana peel .This important theory can help him make a portal in our universal. Unfortunately, making a pair of por

最小生成树之Prim算法和Kruskal算法

一个连通图可能有多棵生成树,而最小生成树是一副连通加权无向图中一颗权值最小的生成树,它可以根据Prim算法和Kruskal算法得出,这两个算法分别从点和边的角度来解决. Prim算法 输入:一个加权连通图,其中顶点集合为V,边集合为E: 初始化:Vn = {x},其中x为集合V中的任一节点(起始点),Enew = {}: 重复下列操作,直到Vn = V:(在集合E中选取权值最小的边(u, v),其中u为集合Vn中的元素,而v则是V中没有加入Vn的顶点(如果存在有多条满足前述条件即具有相同权值的边

经典算法题每日演练——第十六题 Kruskal算法

     这篇我们看看第二种生成树的Kruskal算法,这个算法的魅力在于我们可以打一下算法和数据结构的组合拳,很有意思的. 一:思想     若存在M={0,1,2,3,4,5}这样6个节点,我们知道Prim算法构建生成树是从"顶点"这个角度来思考的,然后采用"贪心思想" 来一步步扩大化,最后形成整体最优解,而Kruskal算法有点意思,它是站在"边"这个角度在思考的,首先我有两个集合. 1. 顶点集合(vertexs):      比如M集合