POJ
来源:互联网 发布:九阴真经捏脸数据 明星 编辑:程序博客网 时间:2024/06/06 15:05
题目大意:
有n(100)头牛,每头牛都有他特定的喜欢吃的食物和牛奶,然后告诉你这些牛都喜欢吃哪些食物和喝哪些牛奶。让你找到一种最佳的分配方式,使得尽量多的牛可以同时得到他喜欢的食物和牛奶。一共存在f(100)种食物和m(100)种牛奶。
分析:
网络流建图:
创建超级源点,超级源点连接所有食物和牛奶,容量为1;每个食物和牛奶分别连接所有喜欢它的牛,容量为1;每个牛连接到超级汇点,容量为2;但是这个有一个问题就是,所有容量为2的边如果走就必须走满。
所以该方法放弃。
只怪自己脑洞不够大,网上别人的建图思路:
创建超级源点,超级源点连接所有食物,容量为1;每个食物分别连接喜欢它的牛的左腿,容量为1;每个牛的左腿连接他自己的右腿,容量为1,每个牛的右腿连接它喜欢的牛奶,容量为1;每个牛奶再连接超级汇点,容量为1;关于为什么要把牛分成两半,是因为,如果不分,那么有可能一个牛作为的结点被多次访问。
代码:
#include<iostream>#include<stdio.h>#include<string.h>#include<queue>#include<math.h>using namespace std;#define maxn 1000#define inf 0x3f3f3fstruct Edge{ int from,to,cap,flow; Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}};int n;int m;vector<Edge>edge;vector<int>G[maxn];int a[maxn];int p[maxn];void init(int n){ for(int i=0;i<n;i++)G[i].clear(); edge.clear();}void add_edge(int from,int to,int cap){ edge.push_back(Edge(from,to,cap,0)); edge.push_back(Edge(to,from,0,0)); int lm=edge.size(); G[from].push_back(lm-2); G[to].push_back(lm-1);}int maxflow(int s,int t){ int flow=0; while(1) { memset(a,0,sizeof(a)); queue<int>Q; Q.push(s); a[s]=inf; while(!Q.empty()) { int x=Q.front();Q.pop(); for(int i=0;i<G[x].size();i++) { Edge& e=edge[G[x][i]]; if(!a[e.to]&&e.cap>e.flow) { p[e.to]=G[x][i]; a[e.to]=min(a[x],e.cap-e.flow); Q.push(e.to); } } if(a[t])break; } if(!a[t])break; for(int u=t;u!=s;u=edge[p[u]].from) { edge[p[u]].flow+=a[t]; edge[p[u]^1].flow-=a[t]; } flow+=a[t]; } return flow;}int f;int main(){ cin>>n>>f>>m;//1 - n牛左,n+1 - 2n牛右,2n+1 - 2n+f食物,2n+1+f - 2n+f+m牛奶,超级源点1,超级汇点2n+f+m+1 int lf,lm;int x; init(maxn); memset(p,0,sizeof(p)); for(int i=1;i<=f;i++)add_edge(0,i+2*n,1); for(int i=1;i<=m;i++)add_edge(2*n+f+i,2*n+f+m+1,1); for(int i=1;i<=n;i++) { add_edge(i,i+n,1); scanf("%d%d",&lf,&lm); for(int j=1;j<=lf;j++) { scanf("%d",&x); add_edge(2*n+x,i,1); } for(int j=1;j<=lm;j++) { scanf("%d",&x); add_edge(i+n,2*n+f+x,1); } } cout<<maxflow(0,2*n+f+m+1)<<endl;}
0 0
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- java实现gzip
- Linux文件管理(1)——文件类型和文件属性
- 分布式消息队列
- ubuntu svn 出现Error validating server certificate for 'https://192.168.1.103:8443'
- 物理内存与虚拟内存区别与联系
- POJ
- BZOJ1432(ZJOI2009)[Function]题解--找规律||数论
- Linux系统中将普通用户添加到sudoers
- MVP详解---利用MVP模式实现一个登录界面
- MySql Join理论以及SQL的解析步骤
- 学习笔记: 源码 relu_layer.cpp 略见
- 字符数组和字符串的区别
- Android中Dialog的使用
- linux内核基础