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

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:3979

    解决:1354

    题目描述:
        省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
    输入:
        测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M (N, M < =100 );随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
    输出:
        对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
    样例输入:
    3 3
    1 2 1
    1 3 2
    2 3 4
    1 3
    2 3 2
    0 100
    样例输出:
    3
    ?
    来源:
    2007年浙江大学计算机及软件工程研究生机试真题

    思路:

    最小生成树问题,并查集求解即可。


    代码:

    #include <stdio.h>
    #include <stdlib.h>
     
    #define N 100
    #define M 100
     
    typedef struct node {
        int x;
        int y;
        int d;
    } 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)
    {
        return (((ROAD *)a)->d > ((ROAD *)b)->d) ? 1 : -1;
    }
     
    int main(void)
    {
        int m, i;
        ROAD r[M];
        int sum;
     
        while (scanf("%d%d", &m, &n) != EOF && m)
        {
            for(i=0; i<m; i++)
                scanf("%d%d%d", &r[i].x, &r[i].y, &r[i].d);
            qsort(r, m, sizeof(r[0]), cmp);
     
            init();
            sum = 0;
            for(i=0; i<m; i++)
            {
                if(combine(r[i].x, r[i].y))
                    sum += r[i].d;
                if (num == 1)
                    break;
            }   
                 
            if (num > 1)
                printf("?
    ");
            else
                printf("%d
    ", sum);
        }       
                 
        return 0;
    }      
    /**************************************************************
        Problem: 1024
        User: liangrx06
        Language: C
        Result: Accepted
        Time:10 ms
        Memory:916 kb
    ****************************************************************/


    编程算法爱好者。
  • 相关阅读:
    [Luogu1993] 小K的农场
    [Noip2013] 车站分级
    [Noip2003]加分二叉树
    [Luogu3797] 妖梦斩木棒
    UPC 6616 Small Mulitple
    STL容器之优先队列
    Dijkstra和Floyd算法
    最短路径问题---Dijkstra算法详解
    并查集
    洛谷 P1217
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5084007.html
Copyright © 2011-2022 走看看