javaee论坛

普通会员

225648

帖子

334

回复

348

积分

楼主
发表于 2019-11-03 15:42:06 | 查看: 340 | 回复: 0

思路

一开始写了网络流,然后就一直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>usingnamespacestd;#definemaxn405#definemaxm1000006#definelllonglongint#defineINF0x3f3f3f3f#defineinc(i,l,r)for(inti=l;i<=r;i++)#definedec(i,r,l)for(inti=r;i>=l;i--)#definemem(a)memset(a,0,sizeof(a))#definesqr(x)(x*x)#defineinf(ll)2e18+1intread(){intx=0,f=1;charch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();returnf*x;}intn,m,a[maxn],b[maxn];intgirl[maxn];boolline[maxn][maxn],used[maxn];boolfind(intx,intl,intr){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;returntrue;}}}returnfalse;}intmain(){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;}intx,y;while(m--){x=read();y=read();mem(girl);intans=0;inc(i,1,n){mem(used);ans+=find(i,x,y);}printf("%d\n",ans);}return0;}

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017