uva 11733 Airports 最小生成树

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2833

题意:n个城市,可以在城市建机场,也可以建道路,要让每个城市都拥有一个机场或者通过道路与有机场的城市相连 求最小花费。

题解:假想一个0号城市,在i城市建立机场就等效于在i城市和0城市之间建一条花费为建立机场费用的路,题目的要求就等效于所有城市(包括0城市)联通。所以只要建图的时候,每个点都与0号城市建立花费为a的路,然后跑一遍最小生成树就可以了。

代码:

#include <iostream>
#include <cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int p[100005];
int n,m,a;
struct node {
	int u,v,w;
}e[1000005];
int finde(int x){
	if(p[x]==x)return x;
	return p[x]=finde(p[x]);
}
void unit(int x,int y){
	x=finde(x);
	y=finde(y);
	p[x]=y;
}
bool same(int x,int y){
	x=finde(x);
	y=finde(y);
	if(x==y)return true;
	return false;
}
void in_it(){
	int i;
	for(i=0;i<=n;i++)p[i]=i;
}
bool cmp(node a,node b){
	if(a.w==b.w)return a.u<b.u;//保证在花费相同时优先建机场
	return a.w<b.w;
}
void kru(){
	int i;
	int ans=0,cnt=0;
	sort(e,e+m,cmp);
	for(i=0;i<m;i++){
		if(same(e[i].u,e[i].v))continue;
		if(e[i].u==0)cnt++;
		unit(e[i].u,e[i].v);
		ans+=e[i].w;
	}
	printf("%d %d\n",ans,cnt);
}
int main()
{
	int t,i,icase=0;
	scanf("%d",&t);
	while(t--){
		icase++;
		scanf("%d%d%d",&n,&m,&a);
		for(i=0;i<m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
		for(i=1;i<=n;i++){//与建立机场等效的道路
			e[m].u=0;
			e[m].v=i;
			e[m].w=a;
			m++;
		}
		in_it();
		printf("Case #%d: ",icase);
		kru();
	}
  //  cout << "Hello world!" << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/nwpu2017300135/article/details/81222423