题目描述:
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
输入:
测试输入包含若干测试用例。每个测试用例的第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;
}