zoukankan      html  css  js  c++  java
  • poj1251 Jungle Roads 最小生成树kruskal算法实现

    题目:
    岛上的居民要修最短的路来使得费用最少
    分析:
    实际上是求最小生成树,可以用prim算法和kruskal算法,
    基于刚学kruskal算法,以下是用kruskal算法做的。

    kruskal算法的思想是:
    先把所有的边按照非降序排列,从而观察每条边是否能与以前
    的边组成环,能的话就不选,不能的话就选择,而判断是否组
    成环路的话可以通过使用并查集实现

    并查集的思想是:
    {1,2,3},{4,5},{6,7,8},{9},当该边是当前最少的边时,两端顶点为
    1,4,因为1,4在两个不同的集合中,故而不能组成回路,假设在同一
    集合中,如1和2,因为前面肯定1,2,3能直接或间接相连接,加入边(1,2)
    可定能使该图组成环路,故而可以用以下代码实现并查集:假设边(u,v)
    的边定点为u[i],v[i],长度为len[i]
    int find_set(int x)
    {
    if(x==union_set[x])
    return x;
    return find_set(union_set[x]);
    }
    以下是main函数里即可实现
    int ans = 0;
    for(int i=0;i<=cnt;i++)
    union_set[i]=i;
    int x = find_set(u[i]);
    int y = find_set(v[i]);
    if(x!=y)
    {
    union_set[y]=x;
    ans+=len[i];
    }
    答案即为ans

    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    #define X 150
    int union_set[80];//并查集
    typedef struct node
    { //定义结构体
    int u,v,len;//顶点,顶点,长度
    }node;
    struct node p[X];
    int find_set(int x)
    { //查找该元素所在集合
    if(x==union_set[x])
    return x;
    return find_set(union_set[x]);
    }
    int cmp(const void *a,const void *b)
    { //强转为结构体排序,按长度的非降排序
    struct node *c = (struct node *)a;
    struct node *d = (struct node *)b;
    return c->len-d->len;
    }
    int main()
    {
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    int n;
    while(cin>>n,n)
    {
    int a,b;
    char ch1,ch2;
    int cnt = 0;
    for(int i=0;i<n-1;i++)
    {
    cin>>ch1>>a;
    for(int j=0;j<a;j++)
    {
    cin>>ch2>>b;
    p[cnt].u = ch1-'A';
    p[cnt].v = ch2-'A';
    p[cnt].len = b;
    cnt++;
    }
    }
    qsort(p,cnt,sizeof(p[0]),cmp);//排序

    //刚开始的时候是n个森林,每一个元素均为该集合的序号
    for(int i=0;i<=cnt;i++)
    union_set[i] = i;
    int ans = 0;
    for(int i=0;i<cnt;i++)
    {
    int x = find_set(p[i].u);//查找顶点所在集合序号
    int y = find_set(p[i].v);
    if(x!=y)
    {
    union_set[y] = x;
    ans += p[i].len;
    }
    }
    cout<<ans<<endl;
    }
    return 0;
    }

  • 相关阅读:
    Fibonacci数列--矩阵乘法优化
    没有上司的舞会--树形DP
    扩展欧几里德--解的个数
    洛谷 P1284 三角形牧场 题解(背包+海伦公式)
    2017-2018 ACM-ICPC Latin American Regional Programming Contest J
    求1-1e11内的素数个数(HDU 5901 Count primes )
    Educational Codeforces Round 96 (Rated for Div. 2) E. String Reversal 题解(思维+逆序对)
    HHKB Programming Contest 2020 D
    牛客练习赛71 数学考试 题解(dp)
    2019-2020 ICPC Asia Hong Kong Regional Contest J. Junior Mathematician 题解(数位dp)
  • 原文地址:https://www.cnblogs.com/yejinru/p/2374696.html
Copyright © 2011-2022 走看看