zoukankan      html  css  js  c++  java
  • HDU 1233 还是畅通工程

    Problem Description
    某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
     
    Input
    测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
    当N为0时,输入结束,该用例不被处理。
     
    Output
    对每个测试用例,在1行里输出最小的公路总长度。
     
    Sample Input
    3
    1 2 1
    1 3 2
    2 3 4
    4
    1 2 1
    1 3 4
    1 4 1
    2 3 3
    2 4 2
    3 4 5
    0
     
    Sample Output
    3
    5
    方法一:该种方法使用于点少,路经多的情况
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    # define N 110
    using namespace std;
    int G[N][N];
    struct node
    {
        int x, y, len;
        friend bool operator < (node a, node b)
        {
            return a.len > b.len;
        }
    }; //优先队列,从小到大排序
    int Prim(int n)
    {
        int i, k = 1, ans = 0, v[N] = {0};
        v[1] = 1; //标志数组,用于判断该点是否已经找到
        node s, e;
        priority_queue<node>Q;
        for (i = 2; i <= n; i++)
        {
            s.x = 1, s.y = i;
            s.len = G[1][i];
            Q.push(s);
        } //先将第一个找到,入队列
        while (k < n)
        {
            s = Q.top();
            Q.pop();
            if (v[s.y] == 0)
            {
                v[s.y] = 1; //将1对应的下一条最短路径找到,置为1
                k++; //记录找到几个点
                ans += s.len; //此时需要加上该最短路径
                for (i = 1; i <= n; i++)
                {
                    e.x = s.y, e.y = i;
                    e.len = G[s.y][i];
                    if (e.len != -1 && v[i] == 0)
                        Q.push(e); //要是该点未被找到且存在路经,入队列
                }
            }
        }
        return ans;
    }
    int main ()
    {
        int i, n, ans, a, b, c;
        while (scanf("%d", &n), n)
        {
            memset(G, -1, sizeof(G)); //以防有些路经不存在
            for (i = 0; i < n*(n-1)/2; i++)
            {
                scanf("%d %d %d", &a, &b, &c);
                G[a][b] = G[b][a] = c; //路经是互通的
            }
            ans = Prim(n);
            printf("%d
    ", ans);
        }
        return 0;
    }
    方法二:该方法适用于点多路径少的情况
    #include<stdio.h>
    #include<queue>
    # define N 110
    using namespace std;
    struct node
    {
        int  x, y, len;
        friend bool operator < (node a, node b)
        {
            return a.len > b.len;
        }
    }; //优先队列,也可以用快排来排序
    int F[N];
    int Find(int x)
    {
        if (x != F[x])
            x = Find(F[x]);
        return x;
    } //查找x的根节点,运用了并查集,这里是为了判断两个点是否在一个集合中
    int main ()
    {
        int i, n, ans;
        while (scanf("%d", &n), n)
        {
            node s;
            priority_queue<node>Q;
            ans = 0;
            for (i = 0; i < n*(n-1)/2; i++)
            {
                scanf("%d %d %d", &s.x, &s.y, &s.len);
                Q.push(s); //输入的时候直接进队列
            }
            for (i = 1; i <= n; i++)
                F[i] = i; //查找根节点的数组要初始化,一开始自己的根节点就是本身
            while (!Q.empty()) //当队列非空时
            {
                s = Q.top();
                Q.pop();
                s.x = Find(s.x);
                s.y = Find(s.y);
                if (s.x != s.y)
                {
                    F[s.x] = s.y;
                    ans += s.len;
                } //若两点不在一个集合,那就在这两点修路,使之在一个集合内
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    SQL语句面试题目:一般查询和高级子查询
    几种常见的排序算法分析学习
    60秒倒计时
    JS倒计时
    sonarqube linux安装总结,集成jenkins
    spring boot打成可执行jar
    Spring Cloud服务间调用鉴权
    Spring Cloud Hystrix熔断器隔离方案
    Spring boot 集成Swagger
    Spring boot 集成Swagger
  • 原文地址:https://www.cnblogs.com/syhandll/p/4470158.html
Copyright © 2011-2022 走看看