Dinic 模板
以后做题就用这个模板了。
题意:一台双核电脑,给你多个任务,分别给出每个任务在第一个核和第二个核上运行的消耗。后面的m行输入是给出两个任务在两个不同核上运行需要付出的额外消耗。
建图:把每个任务作为节点,在超级源点与任务间的连一条边,其容量为给任务在核1上运行的消耗,在该任务节点与超级汇点之间连一条边,容量为该任务在核2上运行的消耗。
在任务之间连接无向边,容量为两个任务不在同一核上运行的额外消耗。
//6132K 2875ms
#include <iostream>
using namespace std;
const int nMax = 20030;
const int mMax = 230000;
const int inf = 0x7fffffff;
int head[nMax], temp[nMax];
int que[nMax], level[nMax];
int ne;
struct Edge
{
int v, c, next;
} edges[2*(nMax+mMax)];
void addEdges(int from, int to, int val1, int val2)
{
edges[ne].v = to;
edges[ne].c = val1;
edges[ne].next = head[from];
head[from] = ne++;
edges[ne].v = from;
edges[ne].c = val2;
edges[ne].next = head[to];
head[to] = ne++;
}
int Dinic(int sta, int end)
{
int max = 0;
int i, k, curr;
while(true)
{
memset(level, -1, sizeof(level));
int f, r;
f = 0; r = 1;
que[0] = sta;
level[sta] = 0;
while(f < r)
{
curr = que[f++];
for(i = head[curr]; i; i = edges[i].next)
if(edges[i].c && level[k = edges[i].v] == -1)
{
level[k] = level[curr] + 1;
que[r++] = k;
if(k == end){ f = r; break; }
}
}
if(level[end] == -1) break;
memcpy(temp, head, sizeof(temp));
int top;
for(curr = sta, top = 0; ;)
{
if(curr == end)
{
int tp = inf;
for(i = 0; i < top; i++)
if(tp > edges[que[i]].c)
tp = edges[que[f = i]].c;
for(i = 0; i < top; i++)
{
edges[que[i]].c -= tp;
edges[que[i]^1].c += tp;
}
top = f;
max += tp; curr = edges[que[top-1]].v;
}
for(i = temp[curr]; temp[curr]; i = temp[curr] = edges[temp[curr]].next)
if(edges[i].c && level[edges[i].v] == level[curr] + 1)
break;
if(temp[curr])
{
que[top++] = temp[curr];
curr = edges[temp[curr]].v;
}
else
{
if(top == 0) break;
level[curr] = -1;
if((top--) == 1)
curr = sta;
else
curr = edges[head[top-1]].v;
}
}
}
return max;
}
int main()
{
int n, m;
int k, j, val1, val2;
int i;
//freopen("a.txt", "r", stdin);
ne = 2;
memset(head, 0, sizeof(head));
scanf("%d%d", &n, &m);
for(i = 1; i <= n; i++)
{
scanf("%d%d", &val1, &val2);
addEdges(0, i, val1, 0);
addEdges(i, n+1, val2, 0);
}
for(i = 1; i <= m; i++)
{
scanf("%d%d%d", &k, &j, &val1);
addEdges(k, j, val1, val1);
}
printf("%d\n", Dinic(0, n+1));
return 0;
}