POJ 1751

此前做过思路类似的,很明显的Kruskal,将一个森林逐渐并成一颗树

又是一个玄学问题,当时写读取顺手写了一个对于多组输入或是单组输入都适用的while写法,不过反而WA了,以后还是具体问题具体分析吧

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;

const int maxn= 755;
const double INF= 1e9;

struct Edge
{
	int u, v;
	double c;
	Edge(int _u= 0, int _v= 0, double _c= 0) : u(_u), v(_v), c(_c) {}
	bool operator < (const Edge &rhs) const
	{
		return c< rhs.c;
	}
}G[maxn*maxn];
int x[maxn], y[maxn];
int fa[maxn], rk[maxn];
int pre[maxn];
double co[maxn];
vector<pair<int, int>> plan;

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

	return fa[x]= Find(fa[x]);
}
void Union(int x, int y)
{
	x= Find(x);
	y= Find(y);

	if (x== y){
		return;
	}

	if (rk[x]> rk[y]){
		fa[y]= x;
		rk[x]+= rk[y];
	}
	else{
		fa[x]= y;
		rk[y]+= rk[x];
	}
}
inline double Dist(int i, int j)
{
	return i== j ? 0 : sqrt(double((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
}
double Kruskal(const int n, const int m, int cnt)
{
	sort(G, G+m);
	double ans= 0, minc;
	int pi;

	for (int i= 0; i< m; ++i){
		int u= G[i].u, v= G[i].v;
		int f_u= Find(u), f_v= Find(v);
		if (f_u== f_v){
			continue;
		}
		ans+= G[i].c;
		Union(u, v);
		plan.push_back(pair<int, int>(u, v));
		if (1== --cnt){
			break;
		}
	}

	return 1== cnt ? ans : -1;
}

int main(int argc, char const *argv[])
{
	int n, m;
	int u, v;
	int cnt;
	scanf("%d", &n);
	plan.clear();
	cnt= n;
	for (int i= 1; i<= n; ++i){
		scanf("%d %d", x+i, y+i);
		fa[i]= i;
		rk[i]= 1;
	}
	scanf("%d", &m);
	for (int i= 0; i< m; ++i){
		scanf("%d %d", &u, &v);
		int fa_u= Find(u), fa_v= Find(v);
		if (fa_u== fa_v){
			continue;
		}
		else{
			--cnt;
			Union(fa_u, fa_v);
		}
	}
	m= 0;
	for (int i= 1; i<= n; ++i){
		for (int j= i+1; j<= n; ++j){
			if (Find(i)== Find(j)){
				continue;
			}
			G[m++]= Edge(i, j, Dist(i, j));
		}
	}
	Kruskal(n, m, cnt);
	for (int i= 0; i< plan.size(); ++i){
		printf("%d %d
", plan[i].first, plan[i].second);
	}
	
	return 0;
}
原文地址:https://www.cnblogs.com/Idi0t-N3/p/14657296.html