暢通工程(2007浙江大學研究生複試上機題[最小生成樹||並查集])

暢通工程
HDU - 1863
時限: 1000MS   內存: 32768KB   64位IO格式: %I64d & %I64u

 狀態

已開啓劃詞翻譯

問題描述點擊打開鏈接 點擊打開鏈接

省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可)。經過調查評估,得到的統計表中列出了有可能建設公路的若干條道路的成本。現請你編寫程序,計算出全省暢通需要的最低成本。 
 

輸入

測試輸入包含若干測試用例。每個測試用例的第1行給出評估的道路條數 N、村莊數目M ( < 100 );隨後的 N 
行對應村莊間道路的成本,每行給出一對正整數,分別是兩個村莊的編號,以及此兩村莊間道路的成本(也是正整數)。爲簡單起見,村莊從1到M編號。當N爲0時,全部輸入結束,相應的結果不要輸出。 
 

輸出

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

樣例輸入

3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
 

樣例輸出

3 ?
 



思路: 

    最小生成樹  杭電 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",&n,&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;
} 


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