Highways POJ - 1751(最小生成树+剪枝)

题目链接

大意:给你n个城市的坐标,再给你m条已经连起来的路,问你还有那些城市需要连起来并且路长最小。

思路:一眼就可以看出是最小生成树,但直接提交会超时,需要剪枝,这题剪枝的技巧在其他最小生成树的题也可以使用(ps:参考博客)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 800 

using namespace std;

struct Edge{
	int u,v;
	float w;
}edge[maxn*maxn];

int n,m,cnt=0,tot=1;//tot记录已经连好的点
int s[maxn],x[maxn],y[maxn];

int find(int u){
	return s[u]==u?u:find(s[u]);
}

bool cmp(const Edge &a,const Edge &b){
	return a.w<b.w;
}

void Kruskal(){
	sort(edge,edge+cnt,cmp);
	for(int i=0;i<cnt;i++){
		int a=find(edge[i].u);
		int b=find(edge[i].v);
		if(a!=b){
			s[b]=a;
			printf("%d %d\n",edge[i].u,edge[i].v);
			tot++;
		}
		if(tot==n){
			break;
		}
	}
}

int main(){
	for(int i=0;i<maxn;i++){
		s[i]=i;
	}
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x[i],&y[i]);
	}
	scanf("%d",&m);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		int a=find(u);
		int b=find(v);
		if(a!=b){
			s[b]=a;
			tot++;
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			float temp=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
			edge[cnt].u=i;
			edge[cnt].v=j;
			edge[cnt++].w=temp;
		}
	}
	Kruskal();
	return 0;
}
发布了16 篇原创文章 · 获赞 0 · 访问量 241
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览