POJ 3436:拆点最大流
来源:互联网 发布:北大燕京学堂知乎 编辑:程序博客网 时间:2024/05/18 02:57
题意:一个电脑有P个部件组成,刚开始所有电脑都是空壳子,当一个电脑具备了所有的N个部件则认为这个电脑早好了。现在有一些机器专门加工电脑,每个机器可以加工某一些特性状态原型机,比如必须具备1部件,必须没有3部件,2部件有没有都行,然后这些原型机经过这个机器的加工,就会变成一种特定状态,比如具备123部件,没有45部件。每个机器每小时可以加工qi个原型机。
求出每小时最多生产多少个成品机。以及流水线的运作情况。
题解:题意特别绕。。。。但是题解是很显然的网络流。对于每个机器,拆成一个入点和出点,入点->出点链接一个容量qi的边。然后二重枚举机器,如果第i个机器的输出可以做得第j个机器的输入,那么就链接i的出点->j的入点,容量INF。然后再开一个超级源,如果裸机可以作为i点的输入,就链接源->i的入点,容量INF。如果第i个机器产出成品机,那就链接i的出点->汇,容量INF。
这里机器的每小时加工数量在入点-出点的边限制住了。
很裸的网络流。。。和网络流基本的油管运输问题基本一摸一样。
Code:
#include<stdio.h>#include<cstring> #include<queue>using namespace std;const int maxn = 55;const int maxp = 15;const int INF = 0x3f3f3f3f;int in[maxn*2][maxp],out[maxn][maxp],q[maxn];int tot,first[maxn],nxt[maxn*maxn],des[maxn*maxn],flow[maxn*maxn];int dep[maxn];int ss,tt;int p,n;inline void addEdge(int x,int y,int z){tot++;des[tot] =y;flow[tot] =z;nxt[tot] = first[x];first[x] = tot;tot++;des[tot] =x;flow[tot] =0;nxt[tot] = first[y];first[y] = tot;}void init(){ss=1;tt=2*n+2;tot =-1;}void input(){//scanf("%d%d",&p,&n);for (int i=2;i<=n+1;i++){scanf("%d",q+i);for (int j=0;j<p;j++){scanf("%d",&in[i][j]);}for (int j=0;j<p;j++){scanf("%d",&out[i][j]);}}}void build (){memset(first,-1,sizeof first);for (int i=2;i<=n+1;i++){addEdge(i,i+n,q[i]);bool flag =true;for (int j=0;j<p;j++){if (in[i][j]==1){flag = false;break;}}if (flag){addEdge(ss,i,INF);}flag = true;for (int j=0;j<p;j++){if (out[i][j]!=1){flag = false;break;}}if (flag){addEdge(i+n,tt,INF);}}for (int i=2;i<=1+n;i++){for (int j=2;j<=1+n;j++){if (i==j)continue;bool flag = true;for (int k=0;k<p;k++){if (out[i][k]==in[j][k]||in[j][k]==2)continue;else{flag = false;break;}}if (flag){addEdge(i+n,j,INF);}}}}bool bfs(){//cout<<"bfs"<<endl;queue<int> Q;memset(dep,-1,sizeof dep);dep[ss]=0;Q.push(ss);while (!Q.empty()){int q = Q.front();Q.pop();for (int t = first[q];t!=-1;t=nxt[t]){int v = des[t];int c = flow[t];if (c&&dep[v]==-1){dep[v] = dep[q]+1;Q.push(v);}}}return dep[tt]!=-1;}int dfs(int node,int now){//cout<<"dfs"<<endl;if (node==tt)return now;int ret =0;for (int t= first[node];t!=-1&&ret<now;t=nxt[t]){int v = des[t];int c = flow[t];if (dep[v]==dep[node]+1&&c){int x = min(c,now-ret);x = dfs(v,x);flow[t]-=x;flow[t^1]+=x;ret+=x;}}if (!ret)dep[node] =-1;return ret;}int max_flow(){int tot =0;while (bfs()){int del;while (del=dfs(ss,INF)){tot+=del;}}return tot;}void solve(){int ans =max_flow();vector<pair<pair<int,int>,int> >list;for (int i=2;i<=n+1;i++){for (int t = first[i];t!=-1;t = nxt[t]){int v = des[t];int c = flow[t];if (c&&v>n+1&&v!=2*n+2&&v!=i+n){//printf("%d %d %d\n",v-n-1,i-1,c);list.push_back(make_pair(make_pair(v-n-1,i-1),c));}}}printf("%d %d\n",ans,list.size());for (int i=0;i<list.size();i++){printf("%d %d %d\n",list[i].first.first,list[i].first.second,list[i].second);}}int main(){while (scanf("%d%d",&p,&n)!=EOF){init();input();build();solve();}return 0;}
阅读全文
0 0
- poj 3436 最大流-拆点
- POJ 3436:拆点最大流
- POJ 3436 ACM Computer Factory 拆点 + 最大流
- poj 3436 最大流+拆点(安装电脑)
- 拆点最大流-POJ-3436-ACM Computer Factory
- poj 2391(最大流+二分+拆点)
- POJ 2391 拆点+最大流+二分
- POJ 3498 拆点 最大流
- poj 3498(最大流+拆点)
- 拆点最大流-POJ-3281-Dining
- poj 2391(二分+拆点+最大流)
- poj 3281 拆点最大流
- poj 3281 Dining(拆点+最大流)
- 【最大流 && 拆点限流】POJ
- POJ---3281 Dining【拆点最大流】
- hdu 2732 / poj 2711 Leapin' Lizards //拆点最大流
- poj 3281 最大流 拆点构图,关键在于构图
- poj 2485 3921 最大流 拆点构图
- Fiddler4入门篇--1(Fiddler的简介以及简单使用)
- python性能测试之 gevent 效果不错
- Ubuntu 14.04 出现 DNS无法解析的问题
- Lucene 理论详解
- 操纵数组内容(Objective-C 开发范例)
- POJ 3436:拆点最大流
- Mongodb Java count 用法记录(嵌套字段也是可以的)
- 我的Qt学习之路——配置Qt环境及Qt程序打包
- 198. House Robber (dp)
- Android自定义view圆形进度条
- 我的读书技巧
- 阿拉伯数字转中文数字
- 自定义view 做一个圆形的progress
- 图像识别与处理之Opencv——基本数据结构及示例