POJ 3436 ACM Computer Factory(Dinic)

版权声明:听说这里让写版权声明~~~ 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]);
	}
}

猜你喜欢

转载自blog.csdn.net/m0_37691414/article/details/82115174