[最大流]BZOJ 1711: [Usaco2007 Open]Dining吃饭 题解
来源:互联网 发布:主人网络关闭了怎么办 编辑:程序博客网 时间:2024/05/18 01:00
本题有权限……
题目描述
农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <= 100) 种食品并准备了D (1 <= D <= 100) 种饮料. 他的N (1 <= N <= 100)头牛都以决定了是否愿意吃某种食物和喝某种饮料. 农夫JOHN想给每一头牛一种食品和一种饮料,使得尽可能多的牛得到喜欢的食物和饮料. 每一件食物和饮料只能由一头牛来用. 例如如果食物2被一头牛吃掉了,没有别的牛能吃食物2.
输入格式
第一行: 三个数: N, F, 和 D
第2..N+1行: 每一行由两个数开始F_i 和 D_i, 分别是第i 头牛可以吃的食品数和可以喝的饮料数.下F_i个整数是第i头牛可以吃的食品号,再下面的D_i个整数是第i头牛可以喝的饮料号码.
输出格式
- 第一行: 一个整数,最多可以喂饱的牛数.
输入样例
4 3 3
2 2 1 2 3 1
2 2 2 3 1 2
2 2 1 3 1 2
2 1 1 3 3
输出样例
3
样例解释:
牛 1: 食品从 {1,2}, 饮料从 {1,2} 中选
牛 2: 食品从 {2,3}, 饮料从 {1,2} 中选
牛 3: 食品从 {1,3}, 饮料从 {1,2} 中选
牛 4: 食品从 {1,3}, 饮料从 {3} 中选
一个方案是:
Cow 1: 不吃
Cow 2: 食品 #2, 饮料 #2
Cow 3: 食品 #1, 饮料 #1
Cow 4: 食品 #3, 饮料 #3
用鸽笼定理可以推出没有更好的解 (一共只有3总食品和饮料).当然,别的数据会更难.
解题分析
这难道是传说中的三分图匹配?算了,我也不会……
可不可以转化成两个独立的二分图匹配?也不行,自己手造一个数据分分钟卡掉。
那么还要怎么做?对于二分图匹配,我们有用最大流的方法来解决,那么这道题应该也可以对题目进行网络流建模再解决,事实上也正是如此。
所以这道题的关键就成了建模……
初始想法是先一列牛再一列食物再一列饮料,但是食物和饮料如何连边?然后就是一个神奇的思路——把牛放中间,这样的话建边就很容易……吗?
这样建图是有问题滴!因为这样一头牛有可能有多个食物的流量进入这个“牛”点,然后又流向多个饮料点最后流到汇点,但这样违反了一头牛只能选一种食物和一种饮料的规则,所以解决方案就是——拆点(这是网络流常用套路之一)。
对于每头牛拆成两个点i1和i2,并额外加一个源点和一个汇点(同样是网络流常用套路之一)那么首先源点向每个食物建一条边,然后食物向想要吃它的牛对应的点i1建一条边,然后i1向i2建一条边,然后i2向想要喝的饮料连一条边,最后所有饮料向汇点连一条边(不得不说太神奇了),所有边的流量限制均为1。
然后Dinic刷最大流就行了,EK貌似不行,e有40000+,EK难以承受,其实DinicO(
复杂度
时间:O(
空间:O(e)
#include<cstdio>#include<cstring>#include<algorithm>#define maxn 405#define maxe 50005using namespace std;const int INF=(((1<<30)-1)<<1)+1;int n,m,k,s,t,tot,lnk[maxn],nxt[maxe],son[maxe],que[maxn],dst[maxn],cap[maxe],flow[maxe],lst[maxn];bool vs[maxn];inline void readi(int &x){ x=0; char ch=getchar(); while ('0'>ch||ch>'9') ch=getchar(); while ('0'<=ch&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}}void _add(int x,int y,int z){ tot++; son[tot]=y; nxt[tot]=lnk[x]; cap[tot]=z; flow[tot]=0; lnk[x]=tot; tot++; son[tot]=x; nxt[tot]=lnk[y]; cap[tot]=0; flow[tot]=0; lnk[y]=tot;}void _init(){ freopen("dingin.in","r",stdin); freopen("dingin.out","w",stdout); memset(lnk,0,sizeof(lnk)); memset(nxt,0,sizeof(nxt)); readi(n); readi(m); readi(k); s=2*n+m+k+1; t=s+1; tot=1; for (int i=1;i<=n;i++) _add(i,i+n,1); for (int i=1;i<=m;i++) _add(s,2*n+i,1); for (int i=1;i<=k;i++) _add(2*n+m+i,t,1); for (int i=1,ka,kb,x;i<=n;i++){ readi(ka); readi(kb); for (int j=1;j<=ka;j++) {readi(x); _add(2*n+x,i,1);} for (int j=1;j<=kb;j++) {readi(x); _add(i+n,2*n+m+x,1);} }}bool _bfs(){ memset(vs,0,sizeof(vs)); memset(dst,0,sizeof(dst)); int hed=0,til=1; que[1]=s; vs[s]=1; dst[s]=0; while (hed!=til){ int x=que[++hed]; for (int j=lnk[x];j;j=nxt[j]) if (!vs[son[j]]&&cap[j]>flow[j]) {que[++til]=son[j]; dst[son[j]]=dst[x]+1; vs[son[j]]=1;} } return vs[t];}int _dfs(int x,int now){ if (x==t||now==0) return now; int tem=0; for (int j=lst[x];j;lst[x]=j=nxt[j]) if (dst[x]+1==dst[son[j]]){ int ew=_dfs(son[j],min(now,cap[j]-flow[j])); if (ew){ tem+=ew; now-=ew; flow[j]+=ew; flow[j^1]-=ew; if (!now) break; } } return tem;}int FDinic(){ int ans=0; while (_bfs()){ for (int i=1;i<=t;i++) lst[i]=lnk[i]; ans+=_dfs(s,INF); } return ans;}void _solve(){ int ans=FDinic(); printf("%d",ans);}int main(){ _init(); _solve(); return 0;}
- [最大流]BZOJ 1711: [Usaco2007 Open]Dining吃饭 题解
- bzoj 1711: [Usaco2007 Open]Dining吃饭 (最大流)
- BZOJ 1711: [Usaco2007 Open]Dining吃饭 最大流
- BZOJ 1711 [Usaco2007 Open]Dining吃饭 最大流
- bzoj 1711: [Usaco2007 Open]Dining吃饭(最大流)
- 【BZOJ1711】[Usaco2007 Open]Dining吃饭【最大流】
- bzoj1711 [Usaco2007 Open]Dining吃饭 最大流
- [bzoj1711][Usaco2007 Open]Dining吃饭 最大流
- bzoj 1711: [Usaco2007 Open]Dining吃饭 网络流
- 1711: [Usaco2007 Open]Dining吃饭
- BZOJ1711 [Usaco2007 Open]Dining吃饭 题解&代码
- [BZOJ1711][Usaco2007 Open]Dining吃饭(最大流)
- BZOJ1711 [ Usaco2007 Open ]Dining吃饭 拆点最大流
- 1711: [Usaco2007 Open]Dingin吃饭 最大流
- 【bzoj1711】[Usaco2007 Open]Dining吃饭
- bzoj1711 [Usaco2007 Open]Dining吃饭
- BZOJ1711: [Usaco2007 Open]Dining吃饭
- bzoj1711 [Usaco2007 Open]Dining吃饭(最大流/三分图匹配)
- 数据库连接池
- 【第四周项目3】单链表应用(二)
- UnityInAppPurchase(Apple&Google)
- 指针数组和数组指针的详细解答
- 数组
- [最大流]BZOJ 1711: [Usaco2007 Open]Dining吃饭 题解
- HBase 通过 Maven 用 Java API 进行增删查put/get/delete
- 两个数的对比
- [算法] LCA 最近公共祖先 (Tarjan)
- 起点
- [USACO FEB14]奶牛的十项全能
- Unity与Android的交互之项目结构
- NOIP2017提高组 模拟赛20(总结)
- LeetCode-82-Remove Duplicates from Sorted List II 链表