洛谷 P2872 [USACO07DEC]Building Roads S

Posted Tecode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P2872 [USACO07DEC]Building Roads S相关的知识,希望对你有一定的参考价值。

题链

先求出每两个点的距离,再根据已有的边,将其赋值为0,然后跑一遍最小生成树;

Kruskal

#include <bits/stdc++.h>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
#define LL long long
#define PI acos(-1.0)
#define eps 1e-8
#define Pair pair<double,double>
// notice
#define mod 998244353 
#define MAXN 2e6
#define MS 1009

LL n,m;
struct node{
	double x,y;
}p[MS];
double dis[MS][MS];
struct nod{
	int u,v;
	double w;
}e[MS*MS];
int fa[MS];
int tot;

bool cmp(nod t1,nod t2){
	return t1.w < t2.w; 
}

double sqr(double x){
	return x*x;
}

double qdis(node t1,node t2){
	return sqrt( sqr(t1.x-t2.x) + sqr(t1.y-t2.y) );
}

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

void merge(int x,int y){
	fa[find(y)] = find(x);
}

int main() {
	//ios::sync_with_stdio(false);
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		double x,y;
		cin >> x >> y;
		p[i] = {x,y};
		fa[i] = i;
	}
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			dis[i][j] = qdis(p[i],p[j]);
		}
	}
	while(m--){
		int u,v;
		cin >> u >> v;
		if(u > v) swap(u,v);
		dis[u][v] = 0;
	}
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			e[++tot] = {i,j,dis[i][j]};
		}
	}
	sort(e+1,e+tot+1,cmp);
	int cc = 0;
	double ans = 0;
	for(int i=1;i<=tot && cc < n-1;i++){
		nod t = e[i];
		if(find(t.u) != find(t.v)){
			ans += t.w;
			merge(t.u,t.v);
			cc++;
		}
	}
	printf("%.2f\\n",ans);

	return 0;
}

Prim

#include <bits/stdc++.h>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
#define LL long long
#define PI acos(-1.0)
#define eps 1e-8
#define Pair pair<double,double>
// notice
#define mod 998244353 
#define MAXN 1e18
#define MS 1009

LL n,m;
struct node{
	double x,y;
}a[MS];
double p[MS][MS];
int v[MS];
double dis[MS];
struct nod{
	int poi;
	double val;
};
priority_queue<nod > Q;

bool operator < (nod t1,nod t2){
	return t1.val > t2.val;
}

double sqr(double x){
	return x*x;
}

double qdis(node t1,node t2){
	return sqrt( sqr(t1.x-t2.x) + sqr(t1.y-t2.y) );
}

double bfs(int x){
	for(int i=1;i<=n;i++){
		dis[i] = MAXN;
	}
	dis[x] = 0;
	Q.push({x,0});
	double ans = 0;
	while(!Q.empty()){
		nod t = Q.top();
		Q.pop();
		if(v[t.poi]) continue;
		v[t.poi] = 1;
		ans += t.val;
		for(int i=1;i<=n;i++){
			if(dis[i] > p[t.poi][i]){
				dis[i] = p[t.poi][i];
				if(!v[i]){
					Q.push({i,p[t.poi][i]});
				}
			}
		}
	}
	return ans;
}

int main() {
	//ios::sync_with_stdio(false);
	cin >> n >> m;
	for(int i=1;i<=n;i++){
		double x,y;
		cin >> x >> y;
		a[i] = {x,y};
	}
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			p[j][i] = p[i][j] = qdis(a[i],a[j]);
		}
	}
	while(m--){
		int u,v;
		cin >> u >> v;
		p[v][u] = p[u][v] = 0;
	}
	double ans = bfs(1);
	printf("%.2f",ans);
	

	return 0;
}

以上是关于洛谷 P2872 [USACO07DEC]Building Roads S的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1626 / P2872 [USACO07DEC]道路建设Building Roads

P2872 [USACO07DEC]Building Roads S

P2872 [USACO07DEC]Building Roads Skruskal

[USACO07DEC]道路建设Building Roads

P2872 [USACO07DEC]Building Roads S(最小生成树)

洛谷 P2868 [USACO07DEC]观光奶牛Sightseeing Cows