題目描述:
省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可)。現得到城鎮道路統計表,表中列出了任意兩城鎮間修建道路的費用,以及該道路是否已經修通的狀態。現請你編寫程序,計算出全省暢通需要的最低成本。
輸入:
測試輸入包含若干測試用例。每個測試用例的第1行給出村莊數目N ( 1< N < 100 );隨後的 N(N-1)/2 行對應村莊間道路的成本及修建狀態,每行給4個正整數,分別是兩個村莊的編號(從1編號到N),此兩村莊間道路的成本,以及修建狀態:1表示已建,0表示未建。
當N爲0時輸入結束。
輸出:
每個測試用例的輸出佔一行,輸出全省暢通需要的最低成本。
樣例輸入:
3
1 2 1 0
1 3 2 0
2 3 4 0
3
1 2 1 0
1 3 2 0
2 3 4 1
3
1 2 1 0
1 3 2 1
2 3 4 1
0
樣例輸出:
3
1
0
來源:
2008年浙江大學計算機及軟件工程研究生機試真題
這道題跟1017題一個套路,用Prim算法,但是,這道題我提交好幾次,一直wrong answer,後來以試試看的心態去掉了對path[][]>0的判斷,就AC了,原來修路也可以沒有花費……
(C語言代碼)
#include<stdio.h>
#include<string.h>
#define N 100
#define MAX 5000
int path[N][N];//路徑長度
int visited[N];
int prim(int n){
int sum= 0, min= MAX;//總路徑, 目前最短
int pa, pb;//最短端點
int num= 0;//走過的點數
int i, j;
for(i= 1; i<= n; i++){
if(visited[i]== 1){
num+= 1;
}
}
if(num== 0){
visited[1]= 1;//1點起
num= 1;
}
while(num< n){
min= MAX;
for(i= 1; i<= n; i++){
if(visited[i]== 1){
for(j= 1; j<= n; j++){
if(visited[j]== 0 ){
if(path[i][j]< min){
min= path[i][j];
pa= i;
pb= j;
}
}
}
}
}
visited[pb]= 1;
sum+= path[pa][pb];
num++;
}
return sum;
}
int main(){
int n;//村莊數
int a, b, c;//臨時變量
int state;//道路狀態
while(scanf("%d", &n)!=EOF && n!= 0){
memset(path, 0, sizeof(path));
memset(visited, 0, sizeof(visited));
for(int i= 0; i< n*(n-1)/2; i++){
scanf("%d %d %d %d", &a, &b, &c, &state);
path[a][b]= path[b][a]= c;
if(state== 1){
visited[a]= 1;
visited[b]= 1;
}
}
if(n== 1){
printf("0\n");
}
else{
printf("%d\n", prim(n));
}
}
return 0;
}