POJ 3281 <最大流,简单的拆点>
2017-06-04 21:32
399 查看
题意:就是给f种食物,d种饮料,有n头牛,每头牛喜欢不同的饮料和食物。
问最大可以满足多少头牛,也就是多少头牛可以同时拥有喜欢的饮料和食物。
刚开始想的是二分图,牛作为边,但是发现如果牛喜欢食物12,喜欢饮料3,4。
那么1-3,2-4如果用最大匹配显然是错的。
那么看起来的二分图可以变成求最大流,建立一个源点连接全部食物,终点连接全部饮料,然后每头牛拆点成2个点,容量为1,2个牛的点放中间,
那么就可以求最大流了。因为每到一次终点都选且仅选一个牛、饮料、食物,所以可以这么建图
建图的时候注意每个点对应的下标。
问最大可以满足多少头牛,也就是多少头牛可以同时拥有喜欢的饮料和食物。
刚开始想的是二分图,牛作为边,但是发现如果牛喜欢食物12,喜欢饮料3,4。
那么1-3,2-4如果用最大匹配显然是错的。
那么看起来的二分图可以变成求最大流,建立一个源点连接全部食物,终点连接全部饮料,然后每头牛拆点成2个点,容量为1,2个牛的点放中间,
那么就可以求最大流了。因为每到一次终点都选且仅选一个牛、饮料、食物,所以可以这么建图
建图的时候注意每个点对应的下标。
#include <iostream> #include <stdio.h> #include <queue> #include <string.h> #include <stdlib.h> using namespace std; struct ttt{ int r,c,s; }; int dr[4]={0,-1,0,1}; int dc[4]={1,0,-1,0}; struct tt2{ int num,cost; }; int map1[505][505]; int cup[505][505]; int flow[505][505]; int pre[550],dist[550]; int walked[550]; int bfs(int a,int b){ memset(pre,-1,sizeof(pre)); memset(walked,0,sizeof(walked)); queue<int>qq; qq.push(a); walked[a]=1; while(!qq.empty()){ int u=qq.front();qq.pop(); for(int i=0;i<=b;i++){ if(cup[u][i]>0&&walked[i]==0){ walked[i]=1; pre[i]=u; if(walked[b]==1)return 1; qq.push(i); } } } return 0; } int max_flow(int a,int b){ int sum=0; while(bfs(a,b)){ int min1=1e9+7; for(int i=b;i!=a;i=pre[i]) min1=min(min1,cup[pre[i]][i]); for(int i=b;i!=a;i=pre[i]){ cup[pre[i]][i]-=min1; } sum+=min1; } return sum; } int main(){ int i,j,k,f1,f2,f3,f4,t1,t2,t3,t4,r,c; freopen("in.txt","r",stdin); int n,m,f,d; cin >> n >> f >> d; memset(map1,0,sizeof(map1)); memset(cup,0,sizeof(cup)); memset(flow,0,sizeof(flow)); int ff,dd; int end1=2*n+f+d+1; for(i=1;i<=n;i++){ cup[i][i+n]=1; } for(i=1;i<=f;i++){ cup[0][i+2*n]=1; } for(i=2*n+f+1;i<end1;i++) cup[i][end1]=1; for(i=1;i<=n;i++){ scanf("%d %d",&ff,&dd); for(j=1;j<=ff;j++){ scanf("%d",&t1); cup[2*n+t1][i]=1; //食物到牛 } for(j=1;j<=dd;j++){ scanf("%d",&t1); cup[i+n][2*n+f+t1]=1; //牛到饮料 } } cout << max_flow(0,end1) << endl; return 0; }
相关文章推荐
- POJ 3449 Geometric Shapes <几何(简单相交判断)>
- POJ 3281 - Dining 简单构图最大流..
- POJ 3281 简单构图+最大流
- POJ 2082 Terrible Sets 51nod 1102 面积最大的矩形 《题意好难懂---<贪心+单调栈>》
- POJ 2446 Chessboard 二分图的最大匹配 <建图>
- POJ 2484 A Funny Game <简单博弈>
- POJ 3469 Dual Core CPU <Dinic + 最小割 + 最大流>
- c#简单实现二维数组和二维数组列表List<>的转置
- <寒江独钓>Windows内核安全编程__一个简单的Windows串口过滤驱动程序的开发
- 简单解决Linq多条件组合问题<转>
- poj 2472 106 miles to Chicago a->b有安全概率,求i->j安全概率最大的一条路
- 简单的区别:<%#eval() %>和<%#bind() %>
- 自定义ORM系列(一)利用attribute实现简单的reader=>entity和reader=>List<entity>映射
- 简单的dp@poj(2)2479最大子段和
- 短信猫软件的实现(C#)<二> AT指令调试器的简单实现
- 简单OS开发前奏<一>EDITPLUS+MASM32搭建汇编开发环境(16位+32位)
- (最大流-简单题) poj 1273 Drainage Ditches
- struts 2 标签之<s:tree/>和<s:treenode/>简单实例
- 轻松简单搭建Linux下的C#开发环境<转>
- 一个简单的List<T>排序的例子