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

    还是畅通工程
    Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
    Submit Status

    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

    Hint

    Hint  Huge input, scanf is recommended.
    中文题,还是最小生成树问题,找最小边权值和,联通所有村庄
    #include<iostream>
    #include<vector>
    #include<queue>
    
    using namespace std;
    
    #define INF 0xfffffff
    #define N 110
    
    int n, G[N][N], vis[N], dist[N];   // dist数组存目前下标联通树上所需最小边权值即距离最小
    
    int prim(int s)
    {
        vis[s] = 1;  // 把s点挂树上,最开始可以任取一点
        dist[s] = 0;  // 自己把自己挂树上,不需要和谁联通,所以距离是0
        int ans = 0;  // ans存目前公路总长度
    
        for(int i = 1; i <= n; i++)
            dist[i] = G[s][i];  // 因为当前只有s点在树上,所以i点挂树上的距离等于i点与s点的距离
    
        for(int i = 1; i < n; i++)  // 因为总共有n个村庄,所以只需要n-1条路
        {
            int index, Min = INF;
    
            for(int j = 1; j <= n; j++)
            {
                if(!vis[j] && dist[j] < Min)
                    Min = dist[j], index = j;  // 寻找目前挂树上的最小距离
            }
    
            vis[index] = 1;  // 把找到的挂树上最小距离的点置为1,表示已经在树上,已经联通
            ans += Min;  // 把最小距离加入ans
    
            for(int j = 1; j <= n; j++)
            {
                if(!vis[j] && dist[j] >= G[index][j])  // 用当前点去更新它所连接的点挂树上的距离(前提比之前挂树上的距离短
                    dist[j] = G[index][j];
            }
        }
    
        return ans;
    }
    int main()
    {
        int a, b, c;
    
        while(cin >> n, n)
        {
            for(int i = 0; i <= n; i++)
            {
                vis[i] = 0;
                dist[i] = INF;
                for(int j = 0; j <= n; j++)
                    G[i][j] = G[j][i] = INF;
                G[i][i] = 0;
            }   // 初始化
    
            for(int i = 0; i < n*(n-1)/2; i++)
            {
                cin >> a >> b >> c;
                G[a][b] = G[b][a] = c;
            }
    
            int ans = prim(1);
    
            cout << ans << endl;
        }
        return 0;
    }

    让未来到来 让过去过去
  • 相关阅读:
    CF710F String Set Queries AC自动机 二进制分组
    类欧几里得学习笔记
    P2053 [SCOI2007]修车 网络流
    螺旋方阵
    灯的排列问题
    编码问题
    论文阅读博客模板
    论文阅读框架模板
    动作识别论文20191104_Probabilistic selection of frames for early action recognition in videos
    剑指offer 57. 数字序列中某一位的数字
  • 原文地址:https://www.cnblogs.com/Tinamei/p/4679263.html
Copyright © 2011-2022 走看看