P3033 [USACO11NOV]Cow Steeplechase G
分析:
-
将横的线段看作一个集合,竖的线段看作另一集合,且集合内部没有关联
容易想到是用二分图最大匹配来解决
-
常规的二分图最大匹配就是求最大匹配的对数,但这题是反过来的
要求两个集合不匹配的线段的个数(即求最大独立集)
结论:最大独立集 = = = 总点数 − - − 最大匹配数(两线段相交即匹配)
-
现在思考这个结论的正确性
若两线段相交,则要去掉一条线段
现已知最多有 m m m 对线段相交,为什么去掉 m m m 条线段就够了
(不知道怎么用言语描述,多画几个图吧…)
-
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+5;
vector <int> g[N];
int b[N], vis[N], pre[N];
bool dfs(int u,int tag)
{
if(vis[u]==tag) return false;
vis[u]=tag;
for(auto v : g[u])
{
if(!pre[v] || dfs(pre[v],tag))
{
pre[v]=u; return true;
}
}
return false;
}
int xa[N][5], ya[N][5];
signed main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n;
cin>>n;
int tox=0, toy=0;
for(int i=1;i<=n;i++)
{
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
if(x1==x2)
{
if(y1>y2) swap(y1,y2);
xa[++tox][0]=x1; xa[tox][1]=y1; xa[tox][2]=y2;
}
else
{
if(x1>x2) swap(x1,x2);
ya[++toy][0]=y1; ya[toy][1]=x1; ya[toy][2]=x2;
}
}
for(int i=1;i<=tox;i++)
{
for(int j=1;j<=toy;j++)
{
if(xa[i][0]>=ya[j][1] && xa[i][0]<=ya[j][2] && ya[j][0]>=xa[i][1] && ya[j][0]<=xa[i][2])
{
g[i].push_back(j);
}
}
}
int ans=0;
for(int i=1;i<=tox;i++)
{
if(dfs(i,i)) ans++;
}
cout<<n-ans<<endl;
return 0;
}