版权声明:听说这里让写版权声明~~~ https://blog.csdn.net/m0_37691414/article/details/82115174
输入:电脑由3个部件组成,共有4台机器,1号机器产量15, 能给空电脑加上2号部件,2号 机器能给空电脑加上2号部件和3号部件, 3号机器能把有1个2号部件和3号部件有无均可的电脑变成成品(每种部件各有一个)
输出:单位时间最大产量25,有两台机器有协作关系,
1号机器单位时间内要将15个电脑给3号机器加工
2号机器单位时间内要将10个电脑给3号机器加工
网络流模型:
解析:
1) 添加一个原点S,S提供最初的原料 00000...
2) 添加一个汇点T, T接受最终的产品 11111...
3) 将每个机器拆成两个点: 编号为i的接收节点,和编号为i+n的产出节点(n是机器数目),前者用于接收原料,后者用于提供加工后的半成品或成品。这两个点之间要连一条边,容量为单位时间产量Qi
4) S 连边到所有接收 "0000..." 或 "若干个0及若干个2" 的机器,容量为无穷大
5) 产出节点连边到能接受其产品的接收节点,容量无穷大
6) 能产出成品的节点,连边到T,容量无穷大。
7) 求S到T的最大流
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1100;
struct node{
int to;
int cap, frow;
int rev;
};
vector<node> v[N];
int level[N], iter[N];
void add_Node(int from, int to, int cap){
v[from].push_back((node){to, cap, cap, v[to].size()});
v[to].push_back((node){from, 0, 0, v[from].size() - 1});
}
void bfs(int s){
memset(level, -1, sizeof(level));
queue<int> q;
level[s] = 0;
q.push(s);
while(!q.empty()){
int t = q.front();
q.pop();
for(int i = 0; i < v[t].size(); ++i){
node &e = v[t][i];
if(e.cap > 0 && level[e.to] == -1){
level[e.to] = level[t] + 1;
q.push(e.to);
}
}
}
}
int dfs(int s, int t, int f){
if(s == t){
return f;
}
for(int &i = iter[s]; i < v[s].size(); ++i){
node &e = v[s][i];
if(level[s] < level[e.to] && e.cap > 0){
int d = dfs(e.to, t, min(f, e.cap));
if(d > 0){
e.cap -= d;
v[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int max_flow(int s, int t){
int flow = 0;
while(true){
bfs(s);
if(level[t] < 0) return flow;
memset(iter, 0, sizeof(iter));
int f;
while((f = dfs(s, t, INF)) > 0){
flow += f;
}
}
}
int main()
{
int s, t, p, n;
int in[110][110], out[110][110], a[110];
while(~scanf("%d%d", &p, &n)) {
memset(v, 0, sizeof(v));
s = 0, t = 2*n + 1;
for(int i = 1; i <= n; ++i){
scanf("%d", &a[i]);
for(int j = 1; j <= p; ++j)
scanf("%d", &in[i][j]);
for(int j = 1; j <= p; ++j)
scanf("%d", &out[i][j]);
}
for(int i = 1; i <= n; ++i){
add_Node(i, i + n, a[i]);
bool flag = true;
for(int j = 1; j <= p; ++j)
if(in[i][j] == 1) flag = false;
if(flag) add_Node(s, i, INF);
flag = true;
for(int j = 1; j <= p; ++j)
if(out[i][j] != 1) flag = false;
if(flag) add_Node(n + i, t, INF);
for(int j = 1; j <= n; ++j){
if(j == i) continue;
flag = true;
for(int k = 1; k <= p; ++k)
if(in[j][k] != 2 && in[j][k] != out[i][k]) flag = false;
if(flag) add_Node(i + n, j, INF);
}
}
int flow = max_flow(s, t);
int k = 0;
int sum[110][3];
for(int i = 1; i < t; ++i)
for(int j = 0; j < v[i].size(); ++j){
node &e = v[i][j];
if(e.to > 0 && e.to <= n && e.cap < e.frow){
sum[++k][0] = i - n, sum[k][1] = e.to, sum[k][2] = e.frow - e.cap;
}
}
printf("%d %d\n", flow, k);
for(int i = 1; i <= k; i++)
printf("%d %d %d\n", sum[i][0], sum[i][1], sum[i][2]);
}
}