7-10 公路村村通 C语言

现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

输入格式:

输入数据包括城镇数目正整数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;
		}
	}
}
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值