最小生成树(优先队列)

最小生成树(优先队列)

最小生成树例题:

最小生成树Kruskal算法
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 227 Accepted: 124

Description

某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了连接两个城镇需要花费的代价。省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可)。问最少花费多少代价就可以完成工程?

Input

输入包含多组数据,对于每组测试数据
第一行包含两个正整数N和M(0 <=N <=1000,0 < M < 5000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以1~N编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0 < A,B <= N ,0 < X < 10000),表示可以在城镇A和城镇B之间建一条花费为X的双向道路。保证数据可以完成工程。

Output

对于每组数据,输出完成工程需要花费的最少代价。

Sample Input

3 4
1 2 3
2 1 4
1 3 1
2 3 2
Sample Output

3

#include<bits/stdc++.h>
using namespace std;
struct node{
	int s,to,w;  //s为起点,to为终点,w为边的权重。
	bool operator <(const node&ths)const{  //重载结构体小于运算符 
	return w>ths.w;
	} 
}; 
int pre[1050];                  //记录根节点 
int find(int x){              //并查集 
	if(x!=pre[x])return pre[x]=find(pre[x]);
	else return x; 
}
int main(){
	priority_queue<node> pq;            //定义优先队列 
	int n,m,a,b,c,i;
	while(scanf("%d %d",&n,&m)!=EOF){
		while(!pq.empty())pq.pop();  //初始化优先队列 
		for(i=0;i<n;i++)pre[i]=i;    //初始化pre数组 
		for(i=0;i<m;i++){
			scanf("%d %d %d",&a,&b,&c);
			pq.push(node{a,b,c});
		}
		int cnt=0,sum=0;                  //cnt记录道路数 ,sum记录花费 
		while(cnt!=n-1){            //最小生成树只有n-1条边 
			node x=pq.top();
			pq.pop();
			if(find(x.s)!=find(x.to)){   //至多只有一个点在树内,保证不成环 
				cnt++;
				pre[find(x.s )]=find(x.to );   //把两个点并入树 
				sum+=x.w;
			} 
		}
		printf("%d\n",sum); 
	}
	return 0; 
}

最小生成树裸题:http://acm.zjnu.edu.cn/CLanguage/showproblem?problem_id=1408
最小生成树的变题:http://acm.zjnu.edu.cn/CLanguage/showproblem?problem_id=2217

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值