标签:
其实就是搬砖
有N个任务,一台双核电脑
每个任务可以在任意且仅一个核上运行
每个在核A上花费Ai,核B上花费Bi
有M对关系,若任务x与任务y不在一个核上运行,则要花费Cx,y
求一种安排任务的方式,使得总花费最小
解法:最小割
源点向每个任务连边,容量Ai
每个任务向汇点连边,容量Bi
对于每一对关系x,y Cx,y:在x与y之间连双向边,容量Cx,y
最小割即为所求
每个任务与S割开表示在A上完成,与T割开表示在B上完成
对于每一对关系x,y Cx,y
若同时在A完成,割开S与x,y之间的边,花费Ax+Ay
若同时在B完成,割开T与x,y之间的边,花费Bx+By
若x在A完成,y在B完成,则割开x,y之间的边,花费Ax+By+Cx,y
#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> #define dprint(expr) fprintf(stderr, #expr " = %d\n", expr) using namespace std; typedef long long LL; typedef pair <int, int> PII; const int N = 2e4 + 7; const int M = 1e6 + 7; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const double EPS = 1e-6; const double PI = acos(-1.0); struct edge { int x, ne, c, f; }; struct NetFlow { edge e[M]; int head[N], h[N], dis[N], q[N], stack[N]; bool used[N]; int pos, stop, top, S, T; LL flow; void init(int s, int t) { pos = 1; flow = top = 0; S = s; T = t; memset(head, 0, sizeof(head)); } void adde(int u, int v, int c) { e[++pos] = (edge){v, head[u], c, 0}; head[u] = pos; e[++pos] = (edge){u, head[v], c, c}; head[v] = pos; } bool number() { memset(dis, 0, sizeof(dis)); memset(used, 0, sizeof(used)); int p1, p2, x; used[q[p1 = p2 = 1] = S] = true; while (p1 <= p2) { x = q[p1++]; for (int i = 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; } bool dinic(int x) { if (x == T) { int cut = INF; for (int i = 1; i <= top; ++i) cut = min(cut, e[stack[i]].c - e[stack[i]].f); for (int i = 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); return flow; } }net; int main(void){ int n, m; while (scanf("%d%d", &n, &m) == 2) { int S = n + 1, T = n + 2; net.init(S, T); for (int i = 1; i <= n; ++i) { int a, b; scanf("%d%d", &a, &b); net.adde(S, i, a); net.adde(i, T, b); } for (int i = 1; i <= m; ++i) { int u, v, w; scanf("%d%d%d", &u, &v, &w); net.adde(u, v, w); net.adde(v, u, w); } int ans = net.maxflow(); printf("%d\n", ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/addf/p/4558359.html