S -> i (cost=Ai,cap=1) S -> i‘(cost=0, cap=1)
i‘-> j (cost=wi,cap=1)(i < j) i -> T (cost=0, cap=1)i -> i‘(×)
1 #include <cstdio> 2 #include <string> 3 #include <vector> 4 #include <queue> 5 #include <cstring> 6 7 typedef long long ll; 8 const int N = 2000; 9 const ll INF = 1e18; 10 11 int read() { 12 int x = 0, f = 1; 13 char c = getchar(); 14 while (!isdigit(c)) { 15 if (c == ‘-‘) f = -1; 16 c = getchar(); 17 } 18 while (isdigit(c)) { 19 x = (x << 3) + (x << 1) + (c ^ 48); 20 c = getchar(); 21 } 22 return x * f; 23 } 24 25 ll min(ll x, ll y) { 26 if (x <= y) return x; return y; 27 } 28 29 int n, m, S, T, A[N]; 30 31 struct Edge { 32 int from, to; ll flow, cap, cost; 33 }; 34 std::vector<Edge> edges; 35 std::vector<int> G[N]; 36 37 int p[N], inq[N]; ll a[N], d[N]; 38 39 bool SPFA(ll &flow, ll &cost) { 40 memset(inq, 0, sizeof inq); 41 for (int i = 0; i < n; ++ i) d[i] = INF; 42 d[S] = p[S] = 0, inq[S] = 1, a[S] = INF; 43 std::queue<int> Q; Q.push(S); 44 while (!Q.empty()) { 45 int u = Q.front(); Q.pop(); inq[u] = 0; 46 int size = G[u].size(); 47 for (int i = 0; i < size; ++ i) { 48 Edge &e = edges[G[u][i]]; 49 if (e.cap > e.flow && d[e.to] > d[u] + e.cost) { 50 d[e.to] = d[u] + e.cost; 51 p[e.to] = G[u][i]; 52 a[e.to] = min(a[u], e.cap - e.flow); 53 if (!inq[e.to]) Q.push(e.to), inq[e.to] = 1; 54 } 55 } 56 } 57 if (d[T] == INF) return false; 58 flow += a[T], cost += a[T] * d[T]; 59 int u = T; 60 while (u != S) { 61 edges[p[u]].flow += a[T]; 62 edges[p[u]^1].flow -= a[T]; 63 u = edges[p[u]].from; 64 } 65 return true; 66 } 67 68 ll minCost() { 69 ll flow = 0, cost = 0; 70 while (SPFA(flow, cost)) {} 71 return cost; 72 } 73 74 void addEdge(int from, int to, ll cap, ll cost) { 75 edges.push_back((Edge){from, to, 0, cap, cost}); 76 edges.push_back((Edge){to, from, 0, 0, -cost}); 77 int size = edges.size(); 78 G[from].push_back(size - 2); 79 G[to].push_back(size - 1); 80 } 81 82 int main() { 83 n = read(), m = read(), S = 0, T = n<<1|1; 84 for (int i = 1; i <= n; ++ i) { 85 A[i] = read(); 86 addEdge(S, (i<<1)-1, 1, A[i]); 87 addEdge(S, i<<1, 1, 0); 88 addEdge((i<<1)-1, T, 1, 0); 89 } 90 for (int i = 1; i <= m; ++ i) { 91 int u = read(), v = read(), w = read(); 92 if (u > v) u ^= v, v ^= u, u ^= v; 93 addEdge(u<<1, (v<<1)-1, 1, w); 94 } 95 n = (n << 1) + 2; 96 printf("%lld\n", minCost()); 97 return 0; 98 }