1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
#include <climits> #include <queue> #include <algorithm> const int MAXN = 1005; const int MAXM = 5005; struct ; struct Node { Edge *e, *curr, *pre; int level, flow, dist; bool inq; } N[MAXN]; struct { Node *u, *v; Edge *next, *rev; int cap, flow, cost; Edge(Node *u, Node *v, int cap, int cost) : u(u), v(v), cap(cap), flow(0), cost(cost), next(u->e) {} }; void addEdge(int u, int v, int cap, int cost) { N[u].e = new Edge(&N[u], &N[v], cap, cost); N[v].e = new Edge(&N[v], &N[u], 0, -cost); N[u].e->rev = N[v].e; N[v].e->rev = N[u].e; } namespace Dinic { bool makeLevelGraph(Node *s, Node *t, int n) { for (int i = 1; i <= n; i++) N[i].level = 0; std::queue<Node *> q; q.push(s); s->level = 1; while (!q.empty()) { Node *u = q.front(); q.pop(); for (Edge *e = u->e; e; e = e->next) { if (e->cap > e->flow && e->v->level == 0) { e->v->level = u->level + 1; if (e->v == t) return true; q.push(e->v); } } } return false; } int findPath(Node *s, Node *t, int limit = INT_MAX) { if (s == t) return limit; for (Edge *&e = s->curr; e; e = e->next) { if (e->cap > e->flow && e->v->level == s->level + 1) { int flow = findPath(e->v, t, std::min(limit, e->cap - e->flow)); if (flow > 0) { e->flow += flow; e->rev->flow -= flow; return flow; } } } return 0; } int solve(int s, int t, int n) { int res = 0; while (makeLevelGraph(&N[s], &N[t], n)) { for (int i = 1; i <= n; i++) N[i].curr = N[i].e; int flow; while ((flow = findPath(&N[s], &N[t])) > 0) res += flow; } return res; } } namespace EdmondsKarp { void solve(int s, int t, int n, int &flow, int &cost) { flow = cost = 0; while (true) { for (int i = 0; i < n; i++) { N[i].dist = INT_MAX; N[i].flow = 0; N[i].pre = NULL; N[i].inq = false; } std::queue<Node *> q; q.push(&N[s]); N[s].dist = 0; N[s].flow = INT_MAX; while (!q.empty()) { Node *u = q.front(); q.pop(); u->inq = false; for (Edge *e = u->e; e; e = e->next) { if (e->cap > e->flow && e->v->dist > u->dist + e->cost) { e->v->dist = u->dist + e->cost; e->v->flow = std::min(u->flow, e->cap - e->flow); e->v->pre = e; if (!e->v->inq) { e->v->inq = true; q.push(e->v); } } } } if (N[t].dist == INT_MAX) break; for (Edge *e = N[t].pre; e; e = e->u->pre) { e->flow += N[t].flow; e->rev->flow -= N[t].flow; } flow += N[t].flow; cost += N[t].dist * N[t].flow; } } } struct Pair { int u, v, cap, cost; } E[MAXM]; int main() { int n, m, k; scanf("%d %d %d", &n, &m, &k); for (int i = 0; i < m; i++) { scanf("%d %d %d %d", &E[i].u, &E[i].v, &E[i].cap, &E[i].cost); addEdge(E[i].u, E[i].v, E[i].cap, 0); } int maxFlow = Dinic::solve(1, n, n); for (int i = 0; i < m; i++) addEdge(E[i].u, E[i].v, INT_MAX, E[i].cost); addEdge(0, 1, k, 0); int flow, cost; EdmondsKarp::solve(0, n, n + 1, flow, cost); printf("%d %dn", maxFlow, cost); return 0; }
|
近期评论