您的位置:首页 > 理论基础 > 数据结构算法

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

2013-11-02 12:50 435 查看
[b]如有错误,请留言提醒,不要坑到小朋友
[/b]
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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分图 数据结构