[BZOJ2502] Cleaning the snow track
Question Description
The ski slopes are located on several hills in the northwestern part of FJ Province. From the aerial view, the ski slopes can be seen as a directed, non-circular map, each arc represents a slope (that is, the snow path), the direction of the arc represents the direction of the slope descent. Your team is responsible for cleaning the slopes regularly every week. You have a helicopter, and each flight can take one person from headquarters to a location on the ski slopes before flying back to headquarters. From the point of landing, the man could glide down the slope and clean up the snow path he had passed. As the cost of each flight is fixed, in order to minimize the cost, you want to know how to use the minimum number of flights to complete the task of cleaning the snow.
Input
The first line of the input file contains an integer n (2 <= n <= 100) – The number of locations representing the ski slopes. The next n lines describe the slopes starting at 1~N , the first number of rows i is mi (0 <= mi < n), followed by a total mi integers, separated by spaces, each integer AIJ , representing a ramp from place I down to the location AIJ . At least one ramp is connected to each location.
Output
The first line of the output file is an integer
k– The minimum number of helicopters flown.
Input example
8 1 3 1 7 2 4 5 1 8 1 8 0 2 6 5 0
Output example
4
Data size and conventions
See " Input "
Exercises
Minimum cost flow. Point-to-point 0 points with an infinite cost of 0 of the forward edge, a forward edge with an infinite cost of 0 for a point to a meeting point of 0, and then for each of the DAG has a forward edge, split into two of the same direction of the forward edge, a capacity of 1 negative infinity, the other infinite cost of 0. Because we need to force each edge to pass at least once, the cost of one of them is set to negative infinity.
Run one side of the minimum cost flow (note not the maximum flow).
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <stack > #include <vector> #include <queue> #include <cstring> #include <string> #include <map > #include <set>using namespace std;const int buffersize = 1 << 16;char buffer[buffersize], *head, *TAIL;INL ine Char Getchar () {if (Head = = Tail) {int L = fread (buffer, 1, buffersize, stdin); Tail = (Head = buffer) + L;} return *head++;} int read () {int x = 0, F = 1, char c = Getchar (), while (!isdigit (c)) {if (c = = '-') f =-1; c = Getchar ();} while (IsDigit (c)) {x = x * + C-' 0 '; c = Getchar ();} return x * f;} #define MAXN 110#define MAXM 40010#define oo 2147483647#define inf 100000#define LL long longstruct Edge {int from, to, F Low, cost; }; struct ZKW {int n, m, S, T, HEAD[MAXN], NEXT[MAXM]; LL cost, ans; Edge Es[maxm];bool INQ[MAXN]; LL d[maxn];bool vis[maxn];void init (int nn) {n = nn; m = 0; memset (head,-1, sizeof); return;} void Addedge (int a,int b, int c, int d) {es[m] = (edge) {A, B, C, d}; next[m] = Head[a]; Head[a] = m++;es[m] = (edge) {b, a, 0,-d}; next[m ] = Head[b]; HEAD[B] = M++;return;} BOOL BFS () {memset (inq, 0, sizeof (INQ)), for (int i = 1; I <= n; i++) d[i] = Oo;deque <int> Q; Q.push_front (t); Inq[t] = 1; D[t] = 0;while (! Q.empty ()) {int u = q.front (); Q.pop_front (); Inq[u] = 0;for (int i = head[u]; i =-1; i = Next[i]) {edge& e = es[i^1];if (E.flow && d[e.from] > D[u] + E. Cost) {D[e.from] = D[u] + e.cost;if (!inq[e.from]) {Inq[e.from] = 1;if (Q.empty () | | d[e.from] <= d[q.front ()]) q.push_fr Ont (e.from); else Q.push_back (E.from);}}} if (d[s] = = oo) return 0;for (int i = 0; i < m; i++) Es[i].cost + = d[es[i].to]-D[es[i].from];cost + = D[s];return 1;} int DFS (int u, int a) {if (U = = T | |!a) {ans + = cost * A; return A;} Vis[u] = 1;int flow = 0, f;for (int i = head[u]; i = 1; i = Next[i]) {edge& e = es[i];if (!vis[e.to] && E.flow &&!e.cost && (f = DFS (e.to, Min (A, E).Flow))) {A-= f; flow + = F;e.flow-F; es[i^1].flow + = F;if (!a) return flow;} return flow;} int Maxflow (int ss, int tt) {s = ss; t = Tt;int flow = 0, Tmp;while (BFS ()) {if (cost >= 0) break;do {memset (Vis, 0, size of (VIS)); tmp = DFS (s, oo); flow + = tmp;} while (TMP);} return flow;}} Sol;int IN[MAXN], Out[maxn];int main () {int n = read (), s = n + 1, t = s + 1;sol.init (n + 2); for (int i = 1; I <= N; i++ {int m = read (), while (m--) {int a = read (); in[a]++; Out[i]++;sol. Addedge (I, a, 1,-inf); Sol. Addedge (i, A, oo, 0);}} for (int i = 1; I <= n; i++) {if (!in[i]) sol. Addedge (S, I, oo, 0); if (!out[i]) sol. Addedge (i, T, Oo, 0);} printf ("%d\n", Sol. Maxflow (S, t)); return 0;}
[BZOJ2502] Cleaning the snow track