[USACO 2011 Nov Gold] Cow Steeplechase【二分图】

传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=93

很容易发现,这是一个二分图的模型。竖直线是X集,水平线是Y集,若某条竖直线与水平线相交,则连边。由于目的是要没有任何两条线相交,所以二分图的边的两端不能同时取,就是要求一个二分图的最大独立集,which equals to N - 最大匹配。

然而啊然而,仍然没有一A!此题只是说给出线段两端点的坐标,并没有说x1一定<x2,y1一定<y2。。。

可以说这是本次月赛金足最水的题,竟然放在第三题,吃鲸。。。

#include <cstdio>
#include <cstring>

const int maxn = 255;

int link[maxn], n, idxx, idxy, match, tem;
bool cover[maxn], g[maxn][maxn];
struct st {
	int x1, y1, x2, y2;
} x[maxn], y[maxn], t;

bool fnd(int i) {
	for (int j = 1; j <= idxy; ++j) {
		if (!cover[j] && g[i][j]) {
			cover[j] = 1;
			if (!link[j] || fnd(link[j])) {
				link[j] = i;
				return true;
			}
		}
	}
	return false;
}

int main(void) {
	freopen("steeple.in", "r", stdin);
	freopen("steeple.out", "w", stdout);
	scanf("%d", &n);
	for (int i = 0; i < n; ++i) {
		scanf("%d%d%d%d", &t.x1, &t.y1, &t.x2, &t.y2);
		if (t.x1 == t.x2) {
			if (t.y1 > t.y2) {
				tem = t.y1;
				t.y1 = t.y2;
				t.y2 = tem;
			}
			x[++idxx] = t;
		}
		else {
			if (t.x1 > t.x2) {
				tem = t.x1;
				t.x1 = t.x2;
				t.x2 = tem;
			}
			y[++idxy] = t;
		}
	}
	
	for (int i = 1; i <= idxx; ++i) {
		for (int j = 1; j <= idxy; ++j) {
			if (x[i].x1 >= y[j].x1 && x[i].x1 <= y[j].x2 &&
				y[j].y1 >= x[i].y1 && y[j].y1 <= x[i].y2) {
					g[i][j] = 1;
			}
		}
	}
	
	for (int i = 1; i <= idxx; ++i) {
		memset(cover, 0, sizeof cover);
		if (fnd(i)) {
			++match;
		}
	}
	printf("%d\n", n - match);
	return 0;
}

  (ps,我写比较长的函数的时候总是在最后忘记return,导致一些奇奇怪怪的错误,以后我需要强制自己写完签名后立即写上return啥!)

posted @ 2016-10-19 21:32  ciao_sora  阅读(340)  评论(0编辑  收藏  举报