【poj3281】【最大流】Dining
来源:互联网 发布:淘宝双十一 实时 编辑:程序博客网 时间:2024/05/16 21:38
一道最大流的简单题。将食物和饮料分别看成一个点集,食物放在左边(记为f[i]),饮料放在右边(记为d[i])。然后将每头牛拆成两个点k,k'
然后开始建图:
1、对于每头牛喜欢的食物和饮料:添加edge(f[i],k,1),edge(d[i],k',1),edge(k,k',1),这样做的目的是为了限制每头牛只能享用一种食物和饮料。
2、对于每个食物和饮料:添加edge(s,f[i],1),edge(d[i],t,1),这样做的目的是限制一种食物和饮料只能选一次。
这样在原图上做一次最大流即为所求,要注意的是拆点时一定要注意好点的映射关系,不能重复映射。
代码:
#include<cstdio>#include<cstring>using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 500;const int maxm = 50000;struct Edge{int c,pos;int next;}E[maxm];int dis[maxn],gap[maxn],pre[maxn],cur[maxn];int head[maxn];int NE = 0;int n,f,d,add;int s,t,nodenum;void init(){freopen("poj3281.in","r",stdin);freopen("poj3281.out","w",stdout);}void insert(int u,int v,int c){E[NE].c = c;E[NE].pos = v;E[NE].next = head[u];head[u] = NE++;E[NE].c = 0;E[NE].pos = u;E[NE].next = head[v];head[v] = NE++;}inline void checkmin(int &a,int b){if(a == -1 || a > b)a = b;}void readdata(){memset(head,-1,sizeof(head));scanf("%d%d%d",&n,&f,&d);add = (n << 1);for(int i = 1;i <= n;i++){int fo,dr;scanf("%d%d",&fo,&dr);for(int j = 1;j <= fo;j++){int tmp;scanf("%d",&tmp);insert(tmp + add,i,1);}for(int j = 1;j <= dr;j++){int tmp;scanf("%d",&tmp);insert(i + n,tmp + add + f,1);}insert(i,i + n,1);}}int sap(){memset(dis,0,sizeof(dis));memset(gap,0,sizeof(gap));for(int i = s;i <= t;i++)cur[i] = head[i];int u = pre[s] = s,maxflow = 0,aug = -1;gap[0] = nodenum;while(dis[s] < nodenum){loop: for(int &i = cur[u];i != -1;i = E[i].next){int v = E[i].pos;if(E[i].c && dis[u] == dis[v] + 1){checkmin(aug,E[i].c);pre[v] = u;u = v;if(v == t){maxflow += aug;for(u = pre[u];v != s;v = u,u = pre[u]){E[cur[u]].c -= aug;E[cur[u]^1].c += aug;}aug = -1;}goto loop;}}int mind = nodenum;for(int i = head[u];i != -1;i = E[i].next){int v = E[i].pos;if(E[i].c && (mind > dis[v])){cur[u] = i;mind = dis[v];}}if((--gap[dis[u]]) == 0)break;gap[dis[u] = mind + 1]++;u = pre[u];}return maxflow;}void solve(){s = 0,t = n * 2 + f + d + 1;nodenum = t + 1;for(int i = 1;i <= f;i++)insert(s,i + add,1);for(int i = 1;i <= d;i++)insert(i + add + f,t,1);printf("%d\n",sap());}int main(){init();readdata();solve();return 0;}
- 【POJ3281 Dining 】最大流
- 【poj3281】【最大流】Dining
- POJ3281 Dining(最大流)
- 【poj3281】Dining 最大流
- POJ3281 Dining 最大流
- 【POJ3281】Dining【最大流】
- poj3281 Dining 最大流
- poj3281 Dining 最大流
- Dining POJ3281 最大流
- POJ3281 Dining [最大流应用]
- POJ3281--Dining(最大流)
- poj3281-Dining ,最大流,建图
- poj3281 Dining(最大流)
- POJ3281 Dining 求最大流
- POJ3281:Dining(最大流)
- poj3281 dining 网络流最大流算法
- POJ3281 Dining,最大流EK算法
- poj3281——Dining(最大流)
- 将24位BMP真彩图转换成BMP灰度图
- VallueStack 在JavaWEb开发中 是strtust2中数据传输的桥梁
- Codejock的使用--皮肤
- 对Thread.interrupt()方法很详细的介绍
- C++几个混淆概念问答
- 【poj3281】【最大流】Dining
- 4_5
- [转载]Codejock Xtreme ToolkitPro MFC 使用
- 我读《清单革命》
- 40岁男人娶20岁女孩
- C#字符串处理机制
- (排序)用C语言实现的直接插入排序
- 位运算符
- Setlocale