POJ 3436 ACM Computer Factory 最大流
题意:一个公司有 n 个机器, 现在一个电脑有 p 个组件,每个机器一分钟能够处理Qi个电脑,前p个数代表的是每个位置的零件的状态 0 代表的是进入到这个机器的电脑 这个位置的零件不能存在 1 代表这个位置的零件一定要有,2代表这个位置的零件可以有也可以没有。 后p个数代表的是,电脑从这个机器出去之后的状态,0代表这个位置没有零件 1代表这个位置有零件。
现在求最大组装电脑的数量,并且要输出流水线状态。
代码跑一下最大流,然后对于每一个正边的流量使用的流量就是反边的流量。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 6 #define LL long long 7 #define ULL unsigned LL 8 #define fi first 9 #define se second 10 #define pb push_back 11 #define lson l,m,rt<<1 12 #define rson m+1,r,rt<<1|1 13 #define lch(x) tr[x].son[0] 14 #define rch(x) tr[x].son[1] 15 #define max3(a,b,c) max(a,max(b,c)) 16 #define min3(a,b,c) min(a,min(b,c)) 17 typedef pair<int,int> pll; 18 const int inf = 0x3f3f3f3f; 19 const LL INF = 0x3f3f3f3f3f3f3f3f; 20 const LL mod = (int)1e9+7; 21 22 const int N = 200; 23 const int M = N*N; 24 int n, m, k; 25 int in[N][15], out[N][15], Q[N]; 26 27 int head[N], deep[N], cur[N]; 28 int w[M], to[M], nx[M]; 29 int tot; 30 void add(int u, int v, int val){ 31 w[tot] = val; to[tot] = v; 32 nx[tot] = head[u]; head[u] = tot++; 33 34 w[tot] = 0; to[tot] = u; 35 nx[tot] = head[v]; head[v] = tot++; 36 } 37 int bfs(int s, int t){ 38 queue<int> q; 39 memset(deep, 0, sizeof(deep)); 40 q.push(s); 41 deep[s] = 1; 42 while(!q.empty()){ 43 int u = q.front(); 44 q.pop(); 45 for(int i = head[u]; ~i; i = nx[i]){ 46 if(w[i] > 0 && deep[to[i]] == 0){ 47 deep[to[i]] = deep[u] + 1; 48 q.push(to[i]); 49 } 50 } 51 } 52 return deep[t] > 0; 53 } 54 int Dfs(int u, int t, int flow){ 55 if(u == t) return flow; 56 for(int &i = cur[u]; ~i; i = nx[i]){ 57 if(deep[u]+1 == deep[to[i]] && w[i] > 0){ 58 int di = Dfs(to[i], t, min(w[i], flow)); 59 if(di > 0){ 60 w[i] -= di, w[i^1] += di; 61 return di; 62 } 63 } 64 } 65 return 0; 66 } 67 68 int Dinic(int s, int t){ 69 int ans = 0, tmp; 70 while(bfs(s, t)){ 71 for(int i = s; i <= t; i++) cur[i] = head[i]; 72 while(tmp = Dfs(s, t, inf)) ans += tmp; 73 } 74 return ans; 75 } 76 void init(){ 77 memset(head, -1, sizeof(head)); 78 tot = 0; 79 } 80 int p; 81 bool check(int x, int y){ 82 for(int i = 1;i <= p; i++){ 83 if(in[y][i] == 0 && out[x][i] == 1) return false; 84 if(in[y][i] == 1 && out[x][i] == 0) return false; 85 } 86 return true; 87 } 88 int au[M], av[M], aw[M]; 89 int main(){ 90 while(~scanf("%d%d", &p, &n)){ 91 init(); 92 for(int i = 1; i <= n; i++){ 93 scanf("%d", &Q[i]); 94 add(i, i+n, Q[i]); 95 for(int j = 1; j <= p; j++) 96 scanf("%d", &in[i][j]); 97 for(int j = 1; j <= p; j++) 98 scanf("%d", &out[i][j]); 99 } 100 int s = 0, t = n*2 + 1; 101 for(int i = 1; i <= n; i++){ 102 int f = 0; 103 for(int j = 1; j <= p; j++){ 104 if(in[i][j] != 2) f += in[i][j]; 105 } 106 if(f == 0) add(s, i, inf); 107 f = 0; 108 for(int j = 1; j <= p; j++) 109 f += out[i][j]; 110 if(f == p) add(i+n, t, inf); 111 } 112 for(int i = 1; i <= n; i++){ 113 for(int j = 1; j <= n; j++){ 114 if(i != j && check(i, j)) 115 add(i+n, j, inf); 116 } 117 } 118 119 printf("%d ", Dinic(s, t)); 120 121 int top = 0; 122 for(int i = 1; i <= n; i++){ 123 for(int j = head[i]; ~j; j = nx[j]){ 124 if(j & 1 && w[j] != 0 && to[j] != s){ 125 top += 1; 126 au[top] = to[j] - n; 127 av[top] = i; 128 aw[top] = w[j]; 129 } 130 131 } 132 } 133 printf("%d\n", top); 134 for(int i = 1; i <= top; i++) 135 printf("%d %d %d\n", au[i], av[i], aw[i]); 136 } 137 return 0; 138 }