惠民工程(2013中南大學研究生複試[最小生成樹])

惠民工程
CSU - 1264
時限: 1000MS   內存: 131072KB   64位IO格式: %lld & %llu

 狀態

已開啓劃詞翻譯

問題描述點擊打開鏈接

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


輸入

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


輸出

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


樣例輸入

3 3
1 2 1
1 3 2
2 3 4
3 1
2 3 2

樣例輸出

3
?

思路: 

   本題與hdoj 1863  暢通工程點擊打開鏈接類似,典型的並查集,或者說是最小生成樹得題目!

#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<algorithm>
using namespace std; 
int pre[1005];
struct node
{
 int p1;
 int p2;//p1,p2分別對應的兩個居民點            
 int v;//鋪設管道所需的費用                  
} way[1005];
int m,n;

void init()
{
	memset(pre,0,sizeof(pre));
	memset(way,0,sizeof(way));
	for(int i=1;i<=m;i++)//初始化,每一個點當做是一個父節點
	 pre[i]=i;
}

int cmp(node a,node b) 
{
return a.v<b.v;
}

int find(int x)//查找父節點                   
{
 int ret=x;
 while(pre[ret]!=ret) //如果查找到的父節點不是它本身,就直接把它當做一個新的父節點
  ret=pre[ret];
  int t=x,r;//下面是路徑壓縮
  while(t!=ret)         
  {
   r=pre[t];   //在改變上一級額的父節點之前 用臨時變量將它記錄起來
   pre[t]=ret;//把上級節點改爲父節點
   t=r;
  }
  return ret;
}

int join(int x,int y)  //判斷兩個點是否連通        
{
  int fx=find(x);
  int fy=find(y);
  if(fx!=fy)//如果已經聯通就不用管,否則將它併入之前的連通分支中                
  {
   pre[fx]=fy;
   return 1;  
  }
  return 0;  
}

int main()
{  
  while(~scanf("%d%d",&m,&n))
  {
   init();
   for(int i=0;i<n;i++)
     scanf("%d%d%d",&way[i].p1,&way[i].p2,&way[i].v);
     
     sort(way,way+n,cmp); //排序,目的是爲了優先考慮成本低的將它併入連通分支  
     
     int ans=0;
      for(int i=0;i<n;i++)
       if(join(way[i].p1,way[i].p2))//如果已經聯通就只需計算管道費用就行 
           ans+=way[i].v;
           
          int count=0;
          for(int i=1;i<=m;i++) 
             if(pre[i]==i)//判斷是否都連通
                 count++;
                
      if(count>1)//如果不連通
        printf("?\n");
        else
          printf("%d\n",ans);
  }
  return 0;
} 






發佈了221 篇原創文章 · 獲贊 17 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章