POJ3565 Ants

原题链接

要求所有线段不相交,实际上满足每条线段的长度和最小。
所以我们可以让蚁窝和苹果树连边,边权为两点的距离,然后就是求二分图带权最小匹配了,可以上(KM)算法或是费用流。
这里我使用的是费用流。

#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int N = 210;
const int M = 1e5 + 10;
struct dd {
	int x, y;
};
dd a[N >> 1];
int fi[N], di[M], da[M], ne[M], q[M << 2], la[N], cn[N], l = 1, st, ed;
double dis[N], co[M];
bool v[N];
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
inline void add(int x, int y, int z, double c)
{
	di[++l] = y;
	da[l] = z;
	co[l] = c;
	ne[l] = fi[x];
	fi[x] = l;
}
inline int minn(int x, int y)
{
	return x < y ? x : y;
}
bool bfs()
{
	int head = 0, tail = 1, i, x, y;
	memset(dis, 66, sizeof(dis));
	q[1] = st;
	dis[st] = 0;
	while (head ^ tail)
	{
		x = q[++head];
		v[x] = 0;
		for (i = fi[x]; i; i = ne[i])
			if (da[i] > 0 && dis[y = di[i]] > dis[x] + co[i])
			{
				dis[y] = dis[x] + co[i];
				la[y] = x;
				cn[y] = i;
				if (!v[y])
				{
					q[++tail] = y;
					v[y] = 1;
				}
			}
	}
	return dis[ed] < 1e8;
}
int main()
{
	int i, j, x, y, n, mi;
	double d;
	n = re();
	st = n << 1 | 1;
	ed = st + 1;
	for (i = 1; i <= n; i++)
	{
		a[i].x = re();
		a[i].y = re();
	}
	for (i = 1; i <= n; i++)
	{
		x = re();
		y = re();
		for (j = 1; j <= n; j++)
		{
			d = sqrt(1.0 * (x - a[j].x) * (x - a[j].x) + 1.0 * (y - a[j].y) * (y - a[j].y));
			add(j, i + n, 1, d);
			add(i + n, j, 0, -d);
		}
	}
	for (i = 1; i <= n; i++)
	{
		add(st, i, 1, 0);
		add(i, st, 0, 0);
		add(i + n, ed, 1, 0);
		add(ed, i + n, 0, 0);
	}
	while (bfs())
	{
		mi = 1e9;
		for (i = ed; i ^ st; i = la[i])
			mi = minn(mi, da[cn[i]]);
		for (i = ed; i ^ st; i = la[i])
		{
			da[cn[i]] -= mi;
			da[cn[i] ^ 1] += mi;
		}
	}
	for (i = 1; i <= n; i++)
		for (j = fi[i]; j; j = ne[j])
		{
			y = di[j];
			if (y > n && y ^ ed && y ^ st && !da[j])
			{
				printf("%d
", y - n);
				break;
			}
		}
	return 0;
}
原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9645842.html