poj1861

题目连接:http://poj.org/problem?id=1861

题目的意思就是找最小生成树

那我们选择kruskal算法  我先来说一下kruskal算法:假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。

下面看代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<iostream>

using namespace std;

#define MAX 15001

int bin[1002];

struct node

{
    int x,y;
    int w;
}edge[MAX],v[MAX];//v用来存用的边 以便输出
int rank[MAX];  //rank[x]代表x的孩子有多少个

int findx(int x)  //找父亲节点的函数

{
    if(x != bin[x])
    {
        bin[x] = findx(bin[x]);
    }
    return bin[x];
    /*int r = x;
    while(r != bin[r])
    {
        r = bin[r];
    }
    return r;*/
}

int cmp(node e1,node e2)
{
    return e1.w < e2.w;
}

void Union(int x,int y)

{
    if(x == y)return;
    if(rank[x] > rank[y])
    {
        bin[y] = x;
    }
    else
    {
        if(rank[x] == rank[y])
        {
            rank[y]++;
        }
        bin[x] = y;
    }
}

int main()

{
    int i,j,n,m,k,max;
    scanf("%d%d",&m,&n);
    for(i = 0;i < n;i++)
    {
        scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].w);
        //printf("%d %d %d*\n",edge[i].x,edge[i].y,edge[i].w);
    }
    for(i = 0;i < m;i++)
    {
        bin[i] = i;    //记录父亲节点
        rank[i] = 0;  //记录儿子节点的个数 为了更新根节点用
    }
    sort(edge,edge + n,cmp);
    k = 0;
    max = 0;
    int a,b;
    for(i = 0;i < n;i++)
    {
        a = findx(edge[i].x);
        b = findx(edge[i].y);
        if(a != b)
        {
            k++;
            //printf("%d %d*\n",edge[i].x,edge[i].y);
            Union(a,b);
            v[k] = edge[i];
            if(edge[i].w > max)
            {
                max = edge[i].w;
            }
        }
    }

    printf("%d\n",max);
    printf("%d\n",k);
    for(i = 1;i <= k;i++)
    {
        printf("%d %d\n",v[i].x,v[i].y);
    }
    return 0;

}
时间: 2024-10-29 19:11:07

poj1861的相关文章

poj1861 最小生成树 prim &amp; kruskal

// poj1861 最小生成树 prim & kruskal // // 一个水题,为的只是回味一下模板,日后好有个照应不是 #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <iostream> using namespace std; const int MAX_N = 1008; const int INF =

poj1861 最小生成树 prim &amp;amp; kruskal

// poj1861 最小生成树 prim & kruskal // // 一个水题,为的仅仅是回味一下模板.日后好有个照顾不是 #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <iostream> using namespace std; const int MAX_N = 1008; const int INF =

POJ1861&amp;ZOJ1542--Network【最小生成树】

链接:http://poj.org/problem?id=1861 最小生成树裸题,输出生成树的最长边.节点个数.节点坐标.另外OJ上样例输出时错的,4个点的最小生成树怎么可能4条边.. 主要是熟悉手写kruskal #include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #in

poj1861最小生成树

#include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include <qu

POJ-1861 Network---最小生成树

题目链接: https://vjudge.net/problem/POJ-1861 题目大意: 有一些公司,公司之间需要连接起来.给出了哪些公司可以连接以及连接边的长度.求最小生成树中最大的边,以及最小生成树的边数,以及输出一颗可行的最小生成树. 思路: 裸的kruskal 这里要求输出的是最大边和边数,不是权值,而且样例是错误的 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include

POJ-1861,Network,最小生成树水题,,注意题面输出有问题,不必理会~~

Network Time Limit: 1000MS   Memory Limit: 30000K          Special Judge http://poj.org/problem?id=1861 Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the compa

POJ1861 Jungle Roads(Kruskal)(并查集)

Jungle Roads Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23882   Accepted: 11193 Description The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads between villages som

POJ1861 Network(Kruskal)(并查集)

Network Time Limit: 1000MS     Memory Limit: 30000K Total Submissions: 16047   Accepted: 6362   Special Judge Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the

POJ1861(Network)-Kruskal

题目在这 Sample Input 4 6 1 2 1 1 3 1 1 4 2 2 3 1 3 4 1 2 4 1 Sample Output 1 4 1 2 1 3 2 3 3 4 题目意思:4个点,6个边,每个边有对应的权值.最后输出一行为路径中最大的边的值,第二行为路径上边的总数, 第三行为每条边的始末编号.题目需要求出最小生成树的最大边的最小值. 1 /* 2 Problem: 1861 User: 3 Memory: 416K Time: 500MS 4 Language: C++ R