HDU 4411 Arrest fee stream
Question link: Click the open link
Question:
Given n + 1 vertex ([0, n]) an undirected graph of m edge. The starting point is 0, and k people are initially at the starting point,
Traversing the graph enables at least one person to walk each vertex and the I-1 must have been traversed when traversing the I point.
To minimize the path and number of k people, k people should return to the starting point.
Ideas:
Cost flow, because for a person, the sequence of the person's traversal points must be an incremental sequence (no need to be continuous)
Therefore, when creating a graph, I only need to connect to the I +? .
If you create a full graph, the spfa runs the negative ring...
# Include
# Include
# Include
# Include
# Include
Using namespace std; # define ll int # define inf 1000000 # define Inf 0x3fffffffffffffll # define N 250 # define m n * 4 struct Edge {ll to, cap, cost, nex; edge () {} Edge (ll to, ll cap, ll cost, ll next): to (to), cap (cap), cost (cost), nex (next) {}} edge [M <1]; ll head [N], edgenum; ll D [N], A [N], P [N]; bool inq [N]; void add (ll from, ll to, ll cap, ll cost) {edge [edgenum] = Edge (to, cap, cost, head [from]); head [from] = edgenum ++; edge [edgenum] = Edge (from, 0,-cost, head [to]); head [to] = edgenum ++;} bool spfa (ll s, ll t, ll & flow, ll & cost) {for (ll I = 0; I <= t; I ++) D [I] = inf; memset (inq, 0, sizeof inq); queue
Q; q. push (s); D [s] = 0; A [s] = inf; while (! Q. empty () {ll u = q. front (); q. pop (); inq [u] = 0; for (ll I = head [u]; ~ I; I = edge [I]. nex) {Edge & e = edge [I]; if (e. cap & D [e. to]> D [u] + e. cost) {D [e. to] = D [u] + e. cost; P [e. to] = I; A [e. to] = min (A [u], e. cap); if (! Inq [e. to]) {inq [e. to] = 1; q. push (e. to) ;}}}// if the fee is inf, stop the billing flow if (D [t] = inf) return false; cost + = D [t] * A [t]; flow + = A [t]; ll u = t; while (u! = S) {edge [P [u]. cap-= A [t]; edge [P [u] ^ 1]. cap + = A [t]; u = edge [P [u] ^ 1]. to;} return true;} ll Mincost (ll s, ll t) {ll flow = 0, cost = 0; while (spfa (s, t, flow, cost )); return cost;} void init () {memset (head,-1, sizeof head); edgenum = 0;} const int MAXN = 105; int g [MAXN] [MAXN]; int n, m, k; void floyd () {for (int k = 0; k <= n; k ++) {for (int I = 0; I <= n; I ++) {for (int j = 0; j <= n; j ++) {if (g [I] [J]> g [I] [k] + g [k] [j]) {g [I] [j] = g [I] [k] + g [k] [j] ;}}} int main () {while (scanf ("% d", & n, & m, & k )! = EOF) {if (n = 0 & m = 0 & k = 0) break; for (int I = 0; I <= n; I ++) {for (int j = 0; j <= n; j ++) g [I] [j] = 10000005; g [I] [I] = 0 ;}for (int I = 0, u, v, w; I <m; I ++) {scanf ("% d", & u, & v, & w ); g [u] [v] = g [v] [u] = min (w, g [u] [v]);} floyd (); init (); int to = n * 2 + 3, from = n * 2 + 2; for (int I = 1; I <= n; I ++) {add (0, I * 2, 1, g [0] [I]); add (I * 2, I * 2 + 1, 1,-inf ); add (I * 2 + 1, to, 1, g [I] [0]); for (int j = I + 1; j <= n; j ++) add (I * 2 + 1, j * 2, 1, g [I] [j]);} add (from, 0, k, 0); add (0, to, k, 0); printf ("% d \ n", Mincost (from, to) + inf * n);} return 0 ;}