Network stream: HDU 3468 Treasure Hunting, hdu3468
Question:
A-Z & a-z indicates the set Node
Starting from point A, go through the shortest step to the next set node (the next set node of a is B, and the next set node of Z is (*) you can pick it up once)
Find the maximum amount of gold that can be picked up at all the collection nodes Starting from point.
Idea: first, use BFS for the I-th set node to find the number of steps required for each point from this set node as D [I] [t]
For any gold, if the shortest Number of two adjacent collection nodes = the number of steps from the gold to the gold, then an edge is created (you can take it)
Then maximize the flow
# Include <cstdio> # include <cstring> # include <cstdlib> # include <string> # include <iostream> # include <algorithm> # include <sstream> # include <cmath> using namespace std; # include <queue> # include <stack> # include <vector> # include <deque> # include <set> # include <map> # include <time. h >;# define cler (arr, val) memset (arr, val, sizeof (arr) # define FOR (I, a, B) for (int I =; I <= B; I ++) # define IN freopen ("in.txt", "r", Stdin); # define OUT freopen ("out.txt", "w", stdout); typedef long LL; const int MAXN = 10014; const int MAXM = 41001; const int INF = 0x3f3f3f; const int mod = 1000000007; struct Edge {int to, next, cap, flow;} edge [MAXM]; // note MAXMint tol; int head [MAXN]; int gap [MAXN], dep [MAXN], cur [MAXN]; void init () {tol = 0; memset (head,-1, sizeof (head);} void addedge (int u, int v, int w, int rw = 0) {edge [tol]. t O = v; edge [tol]. cap = w; edge [tol]. flow = 0; edge [tol]. next = head [u]; head [u] = tol ++; edge [tol]. to = u; edge [tol]. cap = rw; edge [tol]. flow = 0; edge [tol]. next = head [v]; head [v] = tol ++;} int Q [MAXN]; void BFS (int start, int end) {memset (dep,-1, sizeof (dep); memset (gap, 0, sizeof (gap); gap [0] = 1; int front = 0, rear = 0; dep [end] = 0; Q [rear ++] = end; while (front! = Rear) {int u = Q [front ++]; for (int I = head [u]; I! =-1; I = edge [I]. next) {int v = edge [I]. to; if (dep [v]! =-1) continue; Q [rear ++] = v; dep [v] = dep [u] + 1; gap [dep [v] ++ ;}}} int S [MAXN]; int sap (int start, int end, int N) {BFS (start, end); memcpy (cur, head, sizeof (head )); int top = 0; int u = start; int ans = 0; int I; while (dep [start] <N) {if (u = end) {int Min = INF; int inser; for (I = 0; I <top; I ++) {if (Min> edge [S [I]. cap-edge [S [I]. flow) {Min = edge [S [I]. cap-edge [S [I]. flow; inser = I;} For (I = 0; I <top; I ++) {edge [S [I]. flow + = Min; edge [S [I] ^ 1]. flow-= Min;} ans + = Min; top = inser; u = edge [S [top] ^ 1]. to; continue;} bool flag = false; int v; for (I = cur [u]; I! =-1; I = edge [I]. next) {v = edge [I]. to; if (edge [I]. cap-edge [I]. flow & dep [v] + 1 = dep [u]) {flag = true; cur [u] = I; break ;}} if (flag) {S [top ++] = cur [u]; u = v; continue;} int Min = N; for (I = head [u]; I! =-1; I = edge [I]. next) {if (edge [I]. cap-edge [I]. flow & dep [edge [I]. to] <Min) {Min = dep [edge [I]. to]; cur [u] = I ;}} gap [dep [u] --; if (! Gap [dep [u]) return ans; dep [u] = Min + 1; gap [dep [u] ++; if (u! = Start) u = edge [S [-- top] ^ 1]. to;} return ans;} char s [103] [103]; bool vis [103] [103]; int goal [103*103]; int ral [103*103]; int d [53] [101*101]; int n, m; int xx [4] = }; int yy [4] = {0,-1, 1}; void bfs (int x) {memset (d [x], INF, sizeof (d [x]); cler (vis, false); queue <int> q; int t = ral [x]; vis [t/m] [t % m] = true; d [x] [t] = 0; q. push (t); while (! Q. empty () {t = q. front (); q. pop (); int nx = t/m, ny = t % m; for (int I = 0; I <4; I ++) {int dx = nx + xx [I], dy = ny + yy [I]; if (dx> = 0 & dx <n & dy> = 0 & dy <m &&! Vis [dx] [dy] & s [dx] [dy]! = '#') {Vis [dx] [dy] = true; d [x] [dx * m + dy] = d [x] [t] + 1; q. push (dx * m + dy) ;}}} int find (char c) {if ('A' <= c & c <= 'Z ') return c-'A'; if ('A' <= c & c <= 'Z') return c-'A' + 26;} int main () {# ifndef ONLINE_JUDGE freopen ("in.txt", "r", stdin); # endif while (~ Scanf ("% d", & n, & m) {init (); cler (ral, 0); int tol1 = 0, tol2 = 0; for (int I = 0; I <n; I ++) {scanf ("% s", s [I]); for (int j = 0; j <m; j ++) {if (isalpha (s [I] [j]) {ral [find (s [I] [j])] = I * m + j; tol1 ++;} else if (s [I] [j] = '*') goal [tol2 ++] = I * m + j ;}} for (int I = 0; I <tol1; I ++) bfs (I); int flag = 0; for (int I = 1; I <tol1; I ++) for (int j = 0; j <tol2; j ++) {if (d [I] [goal [j] + d [I-1] [goal [j] = d [I-1] [ral [I]) addedge (I, tol1 + j, 1); if (d [I-1] [ral [I] = INF) flag = 1;} if (flag) printf ("-1 \ n"); else {for (int I = 1; I <tol1; I ++) addedge (0, I, 1 ); for (int I = 0; I <tol2; I ++) addedge (tol1 + I, tol1 + tol2, 1); printf ("% d \ n ", sap (0, tol1 + tol2, tol1 + tol2 + 1) ;}} return 0 ;}