P3033 [USACO11NOV]Cow Steeplechase G(二分图最大独立集)

P3033 [USACO11NOV]Cow Steeplechase G(二分图最大独立集)

将有冲突的线段建边,则题目变成求二分图的最大独立集。

最大独立集=结点数-最大匹配。

最小点覆盖=最大匹配。

采用匈牙利算法即可。

时间复杂度: O ( n m ) O(nm) O(nm)

采用bitset 来表示vis数组 会更快。

code

// Problem: P3033 [USACO11NOV]Cow Steeplechase G
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3033
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-07-06 08:50:37
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=255,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define IOS ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\n",a[n]); 
}
struct node{
	int p,l,r;
}a[N],b[N];
int n;
bool ck(node &u,node &v){
	if(u.p<v.l||u.p>v.r) return false;
	if(v.p<u.l||v.p>u.r) return false;
	return true;
}
bitset<N>vis;
int mh[N];
struct edge{
	int to,nt;
}e[M];
int h[N],cnt;
void add(int u,int v){
	e[++cnt]={v,h[u]},h[u]=cnt;
}
bool find(int u){
	for(int i=h[u];i;i=e[i].nt){
		int v=e[i].to;
		if(vis[v]) continue;
		vis[v]=1;
		if(!mh[v]||find(mh[v])){
			mh[v]=u;
			return true;
		}
	}
	return false;
}
int main(){
	scanf("%d",&n);
	int i1=0,i2=0;
	for(int i=1;i<=n;i++){
		int x,y,p,q;
		scanf("%d%d%d%d",&x,&y,&p,&q);
		if(x==p){
			a[++i1]={x,min(y,q),max(y,q)};
		}
		else b[++i2]={y,min(x,p),max(x,p)};
	}
	for(int i=1;i<=i1;i++)
		for(int j=1;j<=i2;j++)
			if(ck(a[i],b[j])) add(i,j);
	int ans=0;
	for(int i=1;i<=i1;i++){
		vis.reset();
		if(find(i)) ans++;
	}
	printf("%d\n",n-ans);
	return 0;
}
上一篇:烂泥:切割nginx日志


下一篇:P1588 [USACO07OPEN]Catch That Cow S