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 ;}
[Network stream] HDU 3468 treasure hunting