惠民工程(最小生成樹)

惠民工程 
 

Description 
市政府“惠民工程”的目標是在全市n個居民點間之架設煤氣管道(但不一定有直接的管道相連,只要能間接通過管道可達即可)。很顯然最多可架設 n(n-1)/2條管道,然而實際上要連通n個居民點只需架設n-1條管道就可以了。現請你編寫程序,計算出該惠民工程需要的最低成本。

Input 
測試輸入包含若干測試用例。每個測試用例的第1行給出居民點數目M ( < =100 )、 評估的管道條數 N;隨後的 N 行對應居民點間管道的成本,每行給出一對正整數,分別是兩個居民點的編號,以及此兩居民點間管道的成本(也是正整數)。爲簡單起見,居民點從1到M編號。

Output 
對每個測試用例,在1行裏輸出全市管道暢通所需要的最低成本。若統計數據不足以保證暢通,則輸出“?”。

Sample Input 
3 3 
1 2 1 
1 3 2 
2 3 4 
3 1 
2 3 2 
Sample Output 
3 
?

 


最小生成樹問題,

使用Prim算法:

#include <iostream>
#include<vector>
#include "stdio.h"


using namespace std;

#define MAX_INT 999999

int main()
{
    int n,m;
    while(scanf("%d%d",&m,&n)==2){
        int s=0,i,j,v,flag=0,sum=0,c;
        vector<vector<int> > a(m,vector<int>(m,MAX_INT));

        while(s++<n){
            //cin>>i>>j>>v;
            scanf("%d%d%d",&i,&j,&v);
            
            
            i--;
            c=i;
            j--;
            a[i][j]=v;
            a[j][i]=v;
        }
        vector<bool> IsInc(m,false);
        IsInc[c]=true;
        for(int k=1;k<m;k++){
            int min_v=MAX_INT,oa,ka;
            for (int ok=0;ok<m;ok++){
                if(IsInc[ok]!=true)
                    continue;

                for(int kl=0;kl<m;kl++){
                    if(IsInc[kl]==false&&a[ok][kl]<min_v&&ok!=kl){
                        //cout<<"*"<<a[ok][kl]<<"*\n";
                        min_v=a[ok][kl];
                        ka=kl;
                        oa=ok;
                    }

                }

            }
            //cout<<"*"<<min_v<<"*\n";
            if(min_v>=MAX_INT)
                flag=1;
            sum+=min_v;
            IsInc[ka]=true;


            if(flag==1)
                break;

        }
        if(flag==1||sum>=MAX_INT)
            cout<<"?\n";
        else
            cout<<sum<<endl;


    }

    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章