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
| #include <cstdio> #include <climits> #include <queue> #include <algorithm> const int MAXN = 505; const int MAXM = 100005; struct Edge; struct Node { Edge *e, *curr; long long w; bool vis; } N[MAXN << 1]; struct Edge { Node *u, *v; Edge *next, *rev; long long w, flow; Edge(Node *u, Node *v, long long w) : u(u), v(v), w(w), flow(0), next(u->e) {} }; void addEdge(int u, int v, long long w, bool di = false) { N[u].e = new Edge(&N[u], &N[v], w); N[v].e = new Edge(&N[v], &N[u], di ? w : 0); N[u].e->rev = N[v].e; N[v].e->rev = N[u].e; } namespace Dijkstra { struct HeapNode { Node *u; int dist; bool operator<(const HeapNode &another) const { return dist > another.dist; } }; void dijkstra(Node *s) { std::priority_queue<HeapNode> q; q.push((HeapNode) {s, 0}); s->w = 0; while (!q.empty()) { Node *u = q.top().u; q.pop(); if (u->vis) continue; u->vis = true; for (Edge *e = u->e; e; e = e->next) { if (e->v->w > u->w + e->w) { e->v->w = u->w + e->w; q.push((HeapNode) {e->v, e->v->w}); } } } } void solve(int s, int n) { for (int i = 1; i <= n; i++) N[i].w = LLONG_MAX; dijkstra(&N[s]); } } namespace Dinic { bool makeLevelGraph(Node *s, Node *t, int n) { for (int i = 1; i <= n; i++) N[i].w = 0; std::queue<Node *> q; q.push(s); s->w = 1; while (!q.empty()) { Node *u = q.front(); q.pop(); for (Edge *e = u->e; e; e = e->next) { if (e->w > e->flow && e->v->w == 0) { e->v->w = u->w + 1; if (e->v == t) return true; q.push(e->v); } } } return false; } long long findPath(Node *s, Node *t, long long limit = LLONG_MAX) { if (s == t) return limit; for (Edge *&e = s->curr; e; e = e->next) { if (e->w > e->flow && e->v->w == s->w + 1) { int flow = findPath(e->v, t, std::min(limit, e->w - e->flow)); if (flow > 0) { e->flow += flow; e->rev->flow -= flow; return flow; } } } return 0; } long long solve(int s, int t, int n) { long long res = 0; while (makeLevelGraph(&N[s], &N[t], n)) { for (int i = 1; i <= n; i++) N[i].curr = N[i].e; long long flow; while ((flow = findPath(&N[s], &N[t])) > 0) res += flow; } return res; } } void clear(int n) { for (int i = 1; i <= n; i++) for (Edge *&e = N[i].e, *next; e; next = e->next, delete e, e = next); } int main() { int n, m; scanf("%d %d", &n, &m); static int E[MAXM][3]; for (int i = 0; i < m; i++) { scanf("%d %d %d", &E[i][0], &E[i][1], &E[i][2]); addEdge(E[i][0], E[i][1], E[i][2], true); } Dijkstra::solve(1, n); clear(n << 1); for (int i = 0; i < m; i++) { int u = E[i][0], v = E[i][1]; long long w = E[i][2]; if (N[u].w + w == N[v].w) addEdge(u + n, v, LLONG_MAX); if (N[v].w + w == N[u].w) addEdge(v + n, u, LLONG_MAX); } for (int i = 1; i <= n; i++) { int c; scanf("%d", &c); addEdge(i, i + n, i != 1 && i != n ? c : LLONG_MAX); } printf("%lld\n", Dinic::solve(1, n << 1, n << 1)); return 0; }
|