zoukankan      html  css  js  c++  java
  • 九度OJ 1028:继续畅通工程 (最小生成树)

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:3140

    解决:1338

    题目描述:
        省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
    输入:
        测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。

        当N为0时输入结束。
    输出:
        每个测试用例的输出占一行,输出全省畅通需要的最低成本。
    样例输入:
    3
    1 2 1 0
    1 3 2 0
    2 3 4 0
    3
    1 2 1 0
    1 3 2 0
    2 3 4 1
    3
    1 2 1 0
    1 3 2 1
    2 3 4 1
    0
    样例输出:
    3
    1
    0
    来源:
    2008年浙江大学计算机及软件工程研究生机试真题

    思路:

    采用并查集求解。

    对道路排序时,第一排序原则是道路是否已经修好,修好的排在前面,第二排序原则是道路的成本。

    先计算已经修好的道路的连通性,然后逐个添加维修好的道路,添加过程中记录新增道路的成本。最后的总成本就是答案。


    代码:

    #include <stdio.h>
    #include <stdlib.h>
     
    #define N 100
    #define M (N*(N-1)/2)
     
    typedef struct node {
        int x;
        int y;
        int d;
        int s;
    } ROAD; 
     
    int n;
    int pre[N+1];
    int count[N+1];
    int num;
             
    void init()
    {
        for (int i=1; i<=n; i++)
        {
            pre[i] = i;
            count[i] = 1;
        }
        num = n; 
    }   
             
    int find(int i)
    {           
        while (i != pre[i]) 
            i = pre[i];
        return i;
    }       
             
    int combine(int i, int j)
    {           
        int a = find(i); 
        int b = find(j);
        if (a != b)
        {   
            if (count[a] > count[b])
            {
                pre[b] = a;
                count[a] += count[b];
                count[b] = 0;
            }
            else
            {
                pre[a] = b;
                count[b] += count[a];
                count[a] = 0;
            }
            num --;
            return 1;
        }
        else
            return 0;
    }
     
    int cmp(const void *a, const void *b)
    {
        ROAD *x = (ROAD *)a;
        ROAD *y = (ROAD *)b;
        if (x->s != y->s)
            return y->s - x->s;
        else
            return x->d - y->d;
    }
     
    int main(void)
    {
        int m, i;
        ROAD r[M];
        int sum;
     
        while (scanf("%d", &n) != EOF && n)
        {
            m = n*(n-1)/2;
            for(i=0; i<m; i++)
                scanf("%d%d%d%d", &r[i].x, &r[i].y, &r[i].d, &r[i].s);
            qsort(r, m, sizeof(r[0]), cmp);
     
            init();
            sum = 0;
            for(i=0; i<m; i++)
            {   
                if(combine(r[i].x, r[i].y) && r[i].s == 0)
                    sum += r[i].d;
                if (num == 1)
                    break;
            }   
                 
            printf("%d
    ", sum);
        }   
             
        return 0;
    }   
    /**************************************************************
        Problem: 1028
        User: liangrx06
        Language: C
        Result: Accepted
        Time:20 ms
        Memory:928 kb
    ****************************************************************/


    编程算法爱好者。
  • 相关阅读:
    SSRS Fields cannot be used in page headers or footers
    mac os x 触摸板点击无效
    Android内核sysfs中switch类使用实例
    hdu1827之强联通
    解决Gradle执行命令时报Could not determine the dependencies of task &#39;:compileReleaseJava&#39;.
    我对Lamport Logical Clock的理解
    側滑删除进阶(七、八)
    管理之路(成长之路--五)
    Qt跨平台的一个例程
    IOS 开发推荐经常使用lib
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5084003.html
Copyright © 2011-2022 走看看