首页 > 代码库 > HDU 1875 畅通工程

HDU 1875 畅通工程

解题思路:

依旧是最小生成树,如果边长小于10或大于1000就跳过,最后看生成树是不是有N - 1条边。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
#define LL long long
#define FOR(i,x,y) for(int i=x;i<=y;i++)
#define rFOR(i,x,y) for(int i=x;i>=y;i--)
using namespace std;
const int maxn = 100 + 10;
struct Point
{
	double x , y;
}P[maxn];
int N , M;
double get_dis(const Point& A , const Point& B)
{
	double x = A.x - B.x;
	double y = A.y - B.y;
	return sqrt(x * x + y * y);
}
struct Edge
{
	int u;
	int v;
	double w;
	bool operator < (const Edge& rhs) const
	{
		return w < rhs.w;
	}
}e[maxn * maxn];
int f[maxn];
int find(int x)
{
	return f[x] == x ? x : f[x] = find(f[x]);
}
void Kruskal()
{
	sort(e , e + M);
	FOR(i,1,N) f[i] = i;
	double ans = 0 ; int n = 0;
	for(int i = 0 ; i < M ; i ++)
	{
		if(e[i].w < 10 || e[i].w > 1000) continue;
		int x = find(e[i].u);
		int y = find(e[i].v);
		if(x != y)
		{
			f[x] = y;
			ans += e[i].w;
			n++;
		}
	}
	if(n == N-1) printf("%.1lf\n",ans*100);
	else printf("oh!\n");
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&N);M = 0;
		FOR(i,1,N) scanf("%lf%lf",&P[i].x , &P[i].y);
		FOR(i,1,N)
		{
			FOR(j,i+1,N)
			{
				double dis = get_dis(P[i] , P[j]);
				e[M].u = i;
				e[M].v = j;
				e[M++].w = dis;
			}
		}
		//for(int i=0;i<M;i++) cout<<e[i].u<<' '<<e[i].v<<' '<<e[i].w<<endl;
		Kruskal();
	}
	return 0;
}

HDU 1875 畅通工程