POJ 1149 (网络流,有趣的建图)
来源:互联网 发布:广州医科大学知乎 编辑:程序博客网 时间:2024/05/01 10:18
网络流(建图是重点)
题意:
有一个卖猪的农夫,他有n个猪圈,但是猪圈的钥匙不在他的手上,有m个顾客,每一个顾客会带一些猪圈的钥匙,每一个顾客都有自己想买猪的数量,当然他所带的钥匙能开启相应的猪圈,从而能买到相应的猪,不过有时猪比他想买的数量多,也有可能少。而农夫有一个权力,就是如果某一个顾客没有买完他开的猪圈里的猪,农夫可以把剩下的猪随意的转移在被这个顾客的开启的猪圈里面。求出农夫最多能卖多少猪?
思路:
切入点应该是“转移”字眼吧,意味着可以用网络流解决问题,因为没有花费的存在,那么就是最大流。
我们知道网络流难点是在于把问题抽象成网络,进而建图。
因为我做的网络流不是很多,不过这道题教会了我一个方法去建图,先把所有条件列在纸上,在纸上试着根据题意建一个图,根据题意的意思是有很多限制条件而重点就是在限制条件上建图,然后手动跑一边网络流看看时都能得到结果。如果能得到,那么很可能就是对的建图。
这道题的建图方式就是:猪圈的猪的限制条件是顾客,我们把源点与猪圈连成边,猪圈和顾客连成边,因为猪圈可能会有多个顾客访问,我们只连最先访问的顾客,如果有多个顾客访问这个猪圈,就把剩下的顾客与第一次访问的顾客相连成边,流量是无限大,这意味着前边顾客买不完的猪可以让后边的顾客买。
最后每一个顾客与汇点连成边流量是顾客买猪的最大值。
- 注意点:顾客与顾客之间建图的时候,注意重边,就是顾客与顾客之间最多建一次就行了。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>using namespace std;const int maxn = 2005;const int INF = 0x3f3f3f3f;struct edge{ int to,cap,rev;};int n,m;vector<edge>G[maxn];int pignum[maxn];int vis[maxn];int level[maxn],iter[maxn];void add_edge(int from,int to,int cap){ int length = G[from].size(); int length1 = G[to].size(); G[from].push_back((edge){to,cap,length1}); G[to].push_back((edge){from,0,length});}void bfs(int s){ memset(level,-1,sizeof(level)); queue<int>Q; Q.push(s); level[s] = 0; while(!Q.empty()) { int to = Q.front(); Q.pop(); int length = G[to].size(); for(int i = 0;i < length; i++) { edge &e = G[to][i]; if(e.cap > 0 && level[e.to] < 0) { level[e.to] = level[to] + 1; Q.push(e.to); } } }}int dfs(int u,int t,int f){ if(u == t) return f; else { int length = G[u].size(); for(int &i = iter[u];i < length; i++) { edge &e = G[u][i]; if(e.cap > 0 && level[e.to] > level[u]) { int d = dfs(e.to,t,min(f,e.cap)); if(d > 0) { e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } } return 0;}int max_flow(int s,int t){ int flow = 0; for(;;) { bfs(s); if(level[t] < 0) break; memset(iter,0,sizeof(iter)); int f; while((f = dfs(s,t,INF)) > 0) { flow += f; } } return flow;}int main(){ //freopen("in.txt","r",stdin); scanf("%d%d",&n,&m); for(int i = 1;i <= n; i++) { scanf("%d",&pignum[i]); add_edge(0,i,pignum[i]); } for(int i = n+1;i <= n+m; i++) { int pighouse; scanf("%d",&pighouse); for(int k = 0;k < pighouse; k++) { int pig; scanf("%d",&pig); if(vis[pig] == 0) { vis[pig] = true; add_edge(pig,i,pignum[pig]); } else { int uppeople = G[pig][1].to; int length = G[uppeople].size(); int flag = true; for(int j = 0;j < length; j++) { if(G[uppeople][j].to == i) { flag = false; break; } } if(flag) { add_edge(uppeople,i,INF); } } } int sum; scanf("%d",&sum); add_edge(i,n+m+1,sum); } printf("%d\n",max_flow(0,n+m+1)); return 0;}
阅读全文
0 0
- POJ 1149 (网络流,有趣的建图)
- poj 1149 网络流
- poj 1149 网络流
- poj 1149 网络流
- POJ 1149 网络流
- poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新
- 一个有趣的网络协议的题目
- POJ 1775 (有趣的简单阶乘)
- 一个有趣的图
- POJ 1573 & POJ 2632(两道有趣的Robot)
- POJ 2773, POJ 3906 有趣的容斥原理
- poj 1149 网络流构图
- poj 1149 PIGS 网络流
- poj 1149 PIGS_网络流
- poj 1149 简单网络流
- poj-1149-PIGS --网络流
- POJ 1149 PIGS 网络流
- poj-1149-PIGS-网络流
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- Linux 网络配置
- Egret踩坑(一)
- C语言的中gets(s)和scanf("%s",s)的区别
- 生活小感悟
- POJ 1149 (网络流,有趣的建图)
- npm配置淘宝镜像仓库以及electron镜像
- Oracle 创建视图、创建存储过程
- 小甲鱼PE详解之输入表(导出表)详解(PE详解09)
- C# Async/Await异步函数原理
- OSG学习:LOD、数据分页、动态调度
- 优化网页速度的7种方法
- 【异常】Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
- JS学习(12)----events