放牧代码和思想
专注自然语言处理、机器学习算法
    This thing called love. Know I would've. Thrown it all away. Wouldn't hesitate.

AOJ 2224 Save your cat 题解 《挑战程序设计竞赛》

AOJ 2224 Save your cat

拯救猫咪:巫女建了一个魔法阵,由N个魔法桩和连接它们的M条魔法篱笆组成。每个由篱笆形成的圈子都至少困住了一只猫咪,而拆篱笆需要耗费等比例的圣水,求最小花费。

2.5 它们其实都是“图”

最小生成树

水题一道,最大生成树之后,不在树中的边就是要拆的篱笆。

有个小插曲,开始给了#define MAX_N 10000 + 1 ,#define MAX_E 10000 + 1 报WA:

Case #27: : Accepted 00.00 sec 1448 [KB] NA NA
Case #28: : Wrong Answer 00.02 sec 1584 [KB] NA NA

后来一想组合数嘛,#define MAX_E MAX_N * (MAX_N – 1) / 2 

然后就

Case #28: : Accepted 00.01 sec 1708 [KB] NA NA
Case #29: : Runtime Error NA NA

后来再加大那么一点点:

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cmath>
#include <iomanip>
using namespace std;

// 并查集相关数据与算法
#define MAX_N 10000 + 16
int parent[MAX_N];
int height[MAX_N];

void init(const int& n)
{
	for (int i = 0; i < n; ++i)
	{
		parent[i] = i;
		height[i] = 0;
	}
}

int find(const int& x)
{
	if (parent[x] == x)
	{
		return x;
	}
	else
	{
		return parent[x] = find(parent[x]);
	}
}

void unite(int x, int y)
{
	x = find(x);
	y = find(y);
	if (x == y)
	{
		return;
	}

	if (height[x] < height[y])
	{
		parent[x] = y;
	}
	else
	{
		parent[y] = x;
		if (height[x] == height[y])
		{
			++height[x];
		}
	}
}

bool same(const int& x, const int& y)
{
	return find(x) == find(y);
}
// End Of 并查集

#define MAX_E MAX_N * MAX_N / 2 + 1
struct edge
{
	int u, v;
	double cost;
	edge(int u = 0, int v = 0, double cost = 0) : u(u), v(v), cost(cost) {}
	bool operator < (const edge & e2) const
	{
		return cost > e2.cost;
	}
};

edge es[MAX_E];
int V, E;
double kruskal()
{
	sort(es, es + E);    // 按照权值从小到大排序
	init(V);
	double res = 0;
	for (int i = 0; i < E; ++i)
	{
		edge e = es[i];
		if (!same(e.u, e.v))
		{
			unite(e.u, e.v);
		}
		else
		{
			res += e.cost;
		}
	}

	return res;
}

pair<int, int> pile[MAX_N];

///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
	cin >> V >> E;
	
	for (int i = 0; i < V; ++i)
	{
		cin >> pile[i].first >> pile[i].second;
	}

	for (int i = 0; i < E; ++i)
	{
		cin >> es[i].u >> es[i].v;
		--es[i].u; --es[i].v;
		int dx = pile[es[i].u].first - pile[es[i].v].first;
		int dy = pile[es[i].u].second - pile[es[i].v].second;
		es[i].cost = sqrt(dx * dx + dy * dy);
	}

	cout.setf(ios::showpoint);
	cout.precision(3);
	cout.setf(ios::fixed);
	cout << kruskal() << endl;
	return 0;
}
///////////////////////////End Sub//////////////////////////////////

就AC了,看来题目中说的N (2 ≤ N ≤ 10000) 有待商榷。

913078 hankcs 2224: Save your cat 32/32 C++ 00.02 s 4056 KB 1943 B 2014-04-14 15:21

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » AOJ 2224 Save your cat 题解 《挑战程序设计竞赛》

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》