is actually moving bricks.
There are n tasks, a dual-core computer
Each task can run on any and only one core
Each spends AI on nuclear a, and nuclear b spends bi
With M-Pair relationships, if task X is not running on a core with task Y, it costs cx,y
Find a way to schedule tasks to minimize total cost
Solution: Minimum Cut
Source points to each task edge, capacity AI
Each task is connected to a meeting point, and the capacity bi
For each pair of relationships X, y cx,y: double-sided between x and Y, capacity cx,y
Minimum cut is what you ask for
Each task with S cut open indicates complete on a, with T cut open to finish on B
For each pair of relationships, X, y cx,y
If you finish at a time, cut off the edge between S and X, Y, and spend Ax+ay
If you finish in B at the same time, cut off the edge between T and X, and spend Bx+by
If X is completed in a and Y is done in B, cut the edge between x, Y and spend ax+by+cx,y
If x is completed in B and Y is completed in a, then cut open the edge between x, Y and spend bx+ay+cx,y purely brick code:
#include <Set>#include<map>#include<queue>#include<deque>#include<cmath>#include<vector>#include<string>#include<cstdio>#include<cstdlib>#include<cstring>#include<cassert>#include<iostream>#include<algorithm>#defineDprint (expr) fprintf (stderr, #expr "=%d\n", expr)using namespaceStd;typedefLong LongLl;typedef pair<int,int>PII;Const intN = 2e4 +7;Const intM = 1e6 +7;Const intINF =0x3f3f3f3f;Const intMOD = 1e9 +7;Const DoubleEPS = 1e-6;Const DoublePI = ACOs (-1.0);structedge{intx, NE, C, f;};structnetflow{Edge E[m]; intHead[n], h[n], dis[n], q[n], stack[n]; BOOLUsed[n]; intPos, Stop, Top, S, T; LL flow; voidInitintSintt) {pos=1; Flow= top =0; S=s; T=T; memset (Head,0,sizeof(head)); } voidAdde (intUintVintc) {e[++pos] = (edge) {V, head[u], C,0}; Head[u]=POS; e[++pos] =(Edge) {u, head[v], C, c}; HEAD[V]=POS; } BOOLNumber () {memset (DIS,0,sizeof(DIS)); memset (Used,0,sizeof(used)); intP1, p2, x; USED[Q[P1= P2 =1] = S] =true; while(P1 <=p2) {x= q[p1++]; for(inti = head[x]; I i =e[i].ne)if(E[i].c > E[I].F &&!)used[e[i].x]) {used[q[++P2] = e[i].x] =true; Dis[e[i].x]= Dis[x] +1; } } if(!Used[t])return false; memcpy (H, head,sizeof(head)); return true; } BOOLDinic (intx) {if(x = =T) {intCut =INF; for(inti =1; I <= top; ++i) Cut= Min (Cut, e[stack[i]].c-e[stack[i]].f); for(inti =1; I <= top; ++i) {e[stack[i]].f+=cut; E[stack[i]^1].F-=cut; if(E[STACK[I]].C = =e[stack[i]].f) Stop=i; } Flow+=cut; return true; } for(int&i = H[x]; I i =e[i].ne)if(E[i].c > E[i].f && dis[x] = = dis[e[i].x]-1) {stack[++top] =i; if(Dinic (e[i].x) && Stop! =top) { --top; return true; } --top; } return false; } LL Maxflow () { while(number ()) dinic (S); returnflow; }}net;intMainvoid){ intN, M; while(SCANF ("%d%d", &n, &m) = =2) { intS = n +1, T = n +2; Net.init (S, T); for(inti =1; I <= N; ++i) {intA, B; scanf ("%d%d", &a, &b); Net.adde (S, I, a); Net.adde (i, T, b); } for(inti =1; I <= m; ++i) {intu, V, W; scanf ("%d%d%d", &u, &v, &W); Net.adde (U, V, W); Net.adde (V, U, W); } intAns =Net.maxflow (); printf ("%d\n", ans); } return 0;}
POJ 3469 Minimum cut theorem