zoukankan      html  css  js  c++  java
  • [最小生成树] 畅通工程

    题目描述

    省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。

    输入

    测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M (N, M < =100 );随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。

    输出

    对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。

    样例输入

    3 4
    1 2 1
    2 3 2
    3 4 3
    2 4
    1 2 1
    3 4 2
    0 5

    样例输出

    6
    ?

    分析:裸的最小生成树问题,直接上代码。

    //邻接矩阵版
    #include <iostream>
    using namespace std;;
    
    const int maxn=200;
    const int INF=1e9;;
    
    int g[maxn][maxn];
    int vis[maxn];
    int d[maxn];
    int n,m;
    
    int prim(int s)
    {
        fill(d,d+maxn,INF);
        fill(vis,vis+maxn,false);
        d[s]=0;
        int ans=0;
        for(int i=0;i<n;i++)
        {
            int u=-1,MIN=INF;
            for(int j=1;j<=n;j++)
            {
                if(vis[j]==false&&d[j]<MIN)
                {
                    u=j;
                    MIN=d[j];
                }
            }
            if(u==-1) return -1;
            vis[u]=true;
            ans+=d[u];
            for(int v=1;v<=n;v++)
            {
                if(vis[v]==false&&g[u][v]!=INF&&g[u][v]<d[v])
                {
                    d[v]=g[u][v];
                }
            }
        }
        return ans;
    }
    
    int main()
    {
        while(cin>>m>>n)
        {
            if(m==0) break;
            fill(g[0],g[0]+maxn*maxn,INF);
            for(int i=0;i<m;i++)
            {
                int u,v;
                cin>>u>>v;
                cin>>g[u][v];
                g[v][u]=g[u][v];
            }
            int ans=prim(1);
            if(ans==-1) cout<<"?"<<endl;
            else cout<<ans<<endl;
        }
    }
    //邻接表法
    #include <iostream>
    #include <vector>
    using namespace std;
    
    const int maxn=300;
    const int INF=1e9;
    
    struct Node
    {
        int v,dis;
    };
    vector<Node> adj[maxn];
    bool vis[maxn];
    int d[maxn];
    int n;
    
    int prim(int s)
    {
        fill(d,d+maxn,INF);
        fill(vis,vis+maxn,false);
        d[s]=0;
        int ans=0;
        for(int i=0;i<n;i++)
        {
            int u=-1,MIN=INF;
            for(int j=1;j<=n;j++)
            {
                if(vis[j]==false&&d[j]<MIN)
                {
                    MIN=d[j];
                    u=j;
                }
            }
            if(u==-1) return -1;
            vis[u]=true;
            ans+=d[u];
            for(int j=0;j<adj[u].size();j++)
            {
                int v=adj[u][j].v;
                int dis=adj[u][j].dis;
                if(vis[v]==false&&dis<d[v])
                {
                    d[v]=dis;
                }
            }
        }
        return ans;
    }
    
    void init()
    {
        for(int i=0;i<maxn;i++)
        {
            adj[i].clear();
        }
    }
    
    
    int main()
    {
        int m;
        while(cin>>m>>n)
        {
            if(m==0) break;
            init();
            for(int i=0;i<m;i++)
            {
                int u,v,wt;
                cin>>u>>v>>wt;
                Node tmp;
                tmp.dis=wt;
                tmp.v=v;
                adj[u].push_back(tmp);
                tmp.v=u;
                adj[v].push_back(tmp);
            }
            int ans=prim(1);
            if(ans==-1) cout<<"?"<<endl;
            else cout<<ans<<endl;
        }
    }
  • 相关阅读:
    ABAP 获取当天的上一个工作日或下一个工作日
    ABAP 增强实战:Enhancement Implementation增强点实施例子
    ABAP Alv输出金额字段时,需要按国家的货币格式显示,列如:JPY
    ABAP 调用程序时获取的数量,金额和日期字段会出现 逗号,-,负号等非法字段,所需要进行转化
    ABAP 调用标准报表程序,获取程序输出list
    ABAP Alv Varient问题:可以更改alv字段布局然后存到Varient中
    ABAP 向下取整和向上取整及取余数
    传统视觉处理方法笔记
    图像特征与描述笔记
    图像预处理笔记
  • 原文地址:https://www.cnblogs.com/xiongmao-cpp/p/6444272.html
Copyright © 2011-2022 走看看