现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。
输入样例:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
输出样例:
12
代码示例:
#include<stdio.h>
#include<stdlib.h>
#define MAXN 1001
int N,M;
struct Node{
int n1,n2,weight;//n1,n2是点
};
void Shell_Sort(struct Node A[], int N);//希尔排序
int GetHead(int a,int head[]);
int main(){
int i,head1,head2;
scanf("%d%d",&N,&M);
struct Node Edge[3*MAXN];
for(i = 0; i < M; i++){
scanf("%d%d%d",&Edge[i].n1,&Edge[i].n2,&Edge[i].weight);
}
Shell_Sort(Edge,M);
int head[N],sum = 0,cnt = 0;//分别是并查集,总权值,边的计数
for(i = 0; i < N; i++){//初始化
head[i] = i;
}
for(i = 0; i < M; i++){
head1 = GetHead(Edge[i].n1-1,head);
head2 = GetHead(Edge[i].n2-1,head);
if(head1 != head2){
head[head1] = head2;
sum += Edge[i].weight;
cnt++;
}
if(cnt == N-1)
break;
}
if(cnt < N-1){
printf("-1");
return 0;
}
printf("%d",sum);
}
int GetHead(int a,int head[]){
if(a == head[a])
return a;
return GetHead(head[a],head);
}
void Shell_Sort(struct Node A[], int N)
{
int P,D,i,Si;
struct Node temp;
int Sedgewick[] = {146305,64769,36289,16001,8929,3905,2161,929, 505, 209, 109, 41, 19, 5, 1, 0};
//插入排序的改版
for ( Si=0; Sedgewick[Si] >= N; Si++ ); /* 初始的增量Sedgewick[Si]不能超过待排序列长度 */
for(; Sedgewick[Si] > 0; Si++){
D = Sedgewick[Si];//这里不能写到上面初始化哦
for(P = D; P < N; P++){
temp = A[P];
for(i = P;i >= D && A[i-D].weight > temp.weight; i -= D){
A[i] = A[i-D];
}
A[i] = temp;
}
}
}