7-95 公路村村通 (30分)--并查集

7-95 公路村村通 (30分)

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

输入格式:
输入数据包括城镇数目正整数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<bits/stdc++.h>
using namespace std;
int p[1009]; 
struct road{
	int s,e,price;
}r[3009];

int find(int x){  
	if(p[x] == x){
		return x;
	}
	return p[x] = find(p[x]);
}

void merge(int x, int y){  
	int xx = find(x), yy = find(y);
	if(xx != yy){
		p[yy] = xx;
	}
}

bool cmp(road &x, road &y){  
	return x.price < y.price;
}

int main()
{
	int n, m, sum=0;
	cin >> n >> m;
	for(int i=1; i<=n; i++){
		p[i] = i;
	}
	for(int i=0; i<m; i++){
		cin >> r[i].s >> r[i].e >> r[i].price;
	}
	sort(r, r+m, cmp);
	for(int i=0; i<m; i++){
		int xx = find(r[i].s), yy = find(r[i].e);
		if(xx != yy){
			p[yy] = xx;
			sum += r[i].price;
		}
	}
	for(int i=1; i<=n; i++){
		p[i] = find(p[i]);
	}
	int cnt=0;
	for(int i=1; i<=n; i++){
		if(p[i]==i){
			cnt++;
		}
	}
	if(cnt > 1){
		cout << -1 << endl;
	}else{
		cout << sum;
	} 
	return 0;
}

欢迎大家批评改正,谢谢!有问题的可以留言,看到一定会回的,让我们共同进步,加油!!!

发布了39 篇原创文章 · 获赞 2 · 访问量 3440

猜你喜欢

转载自blog.csdn.net/weixin_43581819/article/details/103898472