Question:
A directed graph has n (n <= 50) points and M (M <= 4000) edges. Now we need to delete the least vertex so that there is no path with the length from Point 1 to point n <= K (k <1000. Of course, point 1 or point N cannot be deleted directly. The number of points to be deleted at least (the edge connected to the vertex is also deleted when a vertex is deleted ).
PS. No side is directly connected to 1-N.
Ideas:
Minimum Cost flow + split point
Diagram:
(1): Set [2 .. n-1] Split points into I-> I + N connected to a capacity of 1 cost 0 side <>; // ensure that each point is damaged once
(2): Split points 1 and N, and connect one line <INF, 0>; // no damage is guaranteed.
(3): How can I connect an edge (u-> V) with a capacity of U + N-> V equal to INF? <INF, 1>; // determine the cost of each edge
(4): At last, from 1 to 2 * n, we can find the shortest path without stopping, and know that the shortest path is greater than K.
PS. You can also use deep search + enumeration to delete points:
Code:
/* Minimum fee stream + split point * // * AC code: 32 Ms */# include <iostream> # include <cstdio> # include <memory. h >#include <cstdio> # include <cstdlib> # include <queue> # define maxn 200 # define INF 1e8 # define min (a, B) (a <B? A: B) using namespace STD; struct edge {int U, V, W, C, next;} e [20000]; int head [maxn], ecnt; int N, m, K, Scr, sink, vn; bool vis [maxn]; int dis [maxn], pre [maxn]; void insert (int u, int V, int W, int c) {e [ecnt]. U = u; E [ecnt]. V = V; E [ecnt]. W = W; E [ecnt]. C = C; E [ecnt]. next = head [u]; head [u] = ecnt ++; E [ecnt]. U = V; E [ecnt]. V = u; E [ecnt]. W = 0; E [ecnt]. C =-C; E [ecnt]. next = head [v]; head [v] = ecnt ++;} void Init () {int I, U, V; memset (Head,-1, sizeof (head) ); Ecnt = 0; scr = 1; sink = 2 * n; VN = sink; for (I = 2; I <= N-1; I ++) insert (I, I + N,); insert (+ N, INF, 0); insert (N, N + N, INF, 0); for (I = 1; I <= m; I ++) {scanf ("% d", & U, & V); insert (U + N, V, INF, 1) ;}} queue <int> q; bool spfa (int s, int T, int N) {int I, U, V; int C; while (! Q. empty () Q. pop (); memset (VIS, false, sizeof (VIS); for (I = 0; I <= N; I ++) // find the longest path dis [I] = inf; q. push (s); Pre [s] =-1; DIS [s] = 0; vis [s] = true; while (! Q. Empty () {u = Q. Front (); q. Pop (); vis [u] = false; for (I = head [u]; I! =-1; I = E [I]. next) {v = E [I]. v; C = E [I]. c; If (E [I]. w> 0 & dis [v]> dis [u] + C) {dis [v] = dis [u] + C; Pre [v] = I; If (! Vis [v]) {vis [v] = true; q. Push (v) ;}}} if (DIS [T]! = Inf) return true; return false;} void solve () {int I, ANS = 0; while (spfa (SCR, sink, vn )) {If (DIS [sink]> K) break; ans ++; for (I = pre [sink]; I! =-1; I = pre [E [I]. u]) // update {e [I]. w-= 1; E [I ^ 1]. W + = 1 ;}} printf ("% d \ n", ANS);} int main () {While (scanf ("% d ", & N, & M, & K )! = EOF) {If (n = 0 & M = 0 & K = 0) break; Init (); solve () ;}return 0 ;}