您的位置:首页 > 理论基础 > 计算机网络

牛客练习赛51 D 羊吃草 (匈牙利算法 or足够优秀的网络流(不存在的))

2019-09-07 19:43 351 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/lalalafloat/article/details/100605515

大致题意

思路

一开始写了网络流,然后就一直T,但是不重新更新边吧,又会WA。最后终于迫于无奈写了匈牙利。看来是我的网络流太菜了啊!

官方题解:

设坐标轴的整点1…400属于集合A,羊1…n属于集合B,对于编号为i的羊喜欢的区间a[i],b[i],我们在集合B的i点和集合A中的a[i]…b[i]的点之间连一条边,可以发现这样的图是一张二分图。于是对于每次查询l,r,我们枚举集合A中l…r之间的所有点,求出其最大匹配集合。可以用匈牙利算法或足够优秀的最大流。

代码

贴一个匈牙利的板子,一直很少做二分图匹配的题。

#include<bits/stdc++.h>
using namespace std;
#define maxn 405
#define maxm 1000006
#define ll long long int
#define INF 0x3f3f3f3f
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
#define mem(a) memset(a,0,sizeof(a))
#define sqr(x) (x*x)
#define inf (ll)2e18+1
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
int n,m,a[maxn],b[maxn];
int girl[maxn];
bool line[maxn][maxn],used[maxn];
bool find(int x,int l,int r){
inc(j,l,r){
if((line[x][j]==true)&&(used[j]==false)){
used[j]=1;
if (girl[j]==0||find(girl[j],l,r)) {
girl[j]=x;
return true;
}
}
}
return false;
}
int main()
{
n=read();m=read();
inc(i,1,n)a[i]=read();
inc(i,1,n)b[i]=read();
inc(i,1,n){
inc(j,a[i],b[i])line[i][j]=1;
}
int x,y;
while(m--){
x=read();y=read();
mem(girl);
int ans=0;
inc(i,1,n){
mem(used);
ans+=find(i,x,y);
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: