[Usaco2011 Nov]Cow Steeplechase奶牛越野跑(二分圖裸題)

如有錯誤,請留言提醒,不要坑到小朋友

Description




輸入格式: 

*第1行:一個整數:N。 

*第2 .. N +1行:第i +1包含四個空格分開的整數,代表一個障礙:Y1_i X1_i,X2_i,Y2_i。 

SAMPLE INPUT(文件steeple.in): 


4 5 10 5 
6 2 6 12 
8 3 8 5 

輸入詳細信息: 

有三個可供選擇的障礙。第一個是水平段連接(4,5),(10,5),第二和第三是兩條垂直線段(6,2),(6,12),(8,3),(8,5) 。 

輸出格式: 

*第1行:FJ可以選擇的最大障礙數目。 

SAMPLE OUTPUT(文件steeple.out): 



輸出細節: 

最佳的方案是選擇兩個垂直線段(障礙)。

首先,我們很容易看出這是一道二分圖的題

題目中說沒有橫與橫,縱與縱不會相交

所以我們只要考慮橫縱相交的情況,

我們把相交的橫縱連邊,就形成了一個二分圖

然後n-最大匹配就可以了

#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 50100
using namespace std;
struct hg{
	int x1,x2,y;
	hg(){}
	hg(int x1,int x2,int y):x1(x1),x2(x2),y(y){}
}he[maxn];
struct su{
	int x,y1,y2;
	su(){}
	su(int x,int y1,int y2):x(x),y1(y1),y2(y2){}
}sh[maxn];
int sh_tot,he_tot,ans,n,mx[maxn],now[maxn],son[maxn],pre[maxn],tot;
bool bb[maxn];
inline void con(int a,int b){
	pre[++tot]=now[a];
	now[a]=tot;
	son[tot]=b;
}
bool check(int i,int j){
	if(he[i].x1>sh[j].x||sh[j].x>he[i].x2)return 0;
	if(sh[j].y1>he[i].y||he[i].y>sh[j].y2)return 0;
	return 1;
}
bool bfs(int x){
	for(int p=now[x];p;p=pre[p]){
		if(bb[son[p]])continue;
		bb[son[p]]=1;
		if(!mx[son[p]]||bfs(mx[son[p]])){
			mx[son[p]]=x;
			return 1;
		}
	}
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int a,b,c,d;
		scanf("%d%d%d%d",&a,&b,&c,&d);
		if(a==c){
			if(d<b)swap(d,b);
		sh[++sh_tot]=su(a,b,d);
		}
		else {
			if(c<a)swap(c,a);
			he[++he_tot]=hg(a,c,d);
		}
	}
	for(int i=1;i<=he_tot;i++)
		for(int j=1;j<=sh_tot;j++)if(check(i,j))con(i,j);
	for(int i=1;i<=he_tot;i++){
		memset(bb,0,sizeof(bb));
		if(bfs(i))ans++;
	}
	printf("%d\n",n-ans);
	system("pause");
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章