zoukankan      html  css  js  c++  java
  • 九度OJ 1347:孤岛连通工程 (最小生成树)

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:1522

    解决:314

    题目描述:

    现在有孤岛n个,孤岛从1开始标序一直到n,有道路m条(道路是双向的,如果有多条道路连通岛屿i,j则选择最短的那条),请你求出能够让所有孤岛都连通的最小道路总长度。

    输入:

    数据有多组输入。
    每组第一行输入n(1<=n<=1000),m(0<=m<=10000)。
    接着m行,每行输入一条道路i j d(0<=d<=1000),(i,j表示岛屿序号,d表示道路长度)。

    输出:

    对每组输入输出一行,如果能连通,输出能连通所有岛屿的最小道路长度,否则请输出字符串"no"。

    样例输入:
    3 5
    1 2 2
    1 2 1
    2 3 5
    1 3 3
    3 1 2
    4 2
    1 2 3
    3 4 1
    样例输出:
    3
    no

    思路:

    利用并查集求最小生成树,如果失败则输出no


    代码:

    #include <stdio.h>
    #include <stdlib.h>
     
    #define N 1000
    #define M 10000
     
    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", &n, &m) != EOF)
        {
            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("no
    ");
            else
                printf("%d
    ", sum);
        }
     
        return 0;
    }
    /**************************************************************
        Problem: 1347
        User: liangrx06
        Language: C
        Result: Accepted
        Time:910 ms
        Memory:972 kb
    ****************************************************************/


  • 相关阅读:
    处理SVN的提交代码冲突
    Oracle对表解锁的操作
    Eclipse 安装反编译插件jadclipse
    如何由jdk的安装版本改成非安装版本
    ASP.NET Web API与Rest web api(一)
    使用C#发送正文带图片邮件
    Silverlight页面通过继承扩展实现
    九度 1347:孤岛连通工程(最小生成树)
    九度 1209:最小邮票数(多重背包)
    利用栈将中缀表达式转化成后缀表达式
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083786.html
Copyright © 2011-2022 走看看