A person to go from a city to B city, each road only allowed to walk once, ask can walk a few short-circuit
Problem-solving ideas: This problem, the difficulty is how to know if it is the shortest
First, we find the shortest path to B, which also gives the shortest distance from all points to B.
Then we find out the shortest path to a.
This allows you to get two arrays, assuming d1[u] represents the shortest path for the U-node to City D2[v], which represents the shortest distance from the V node to City B.
If meet D1[u] + Dis[u][v] + d2[v] = = D1[v], then u,v this road belongs to the shortest path in the side, so you can construct the side
We have to split the city into two points with a capacity of 1.
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace STD;#define N 1010#define INF 0x3f3f3f3fstructEdge {intFrom, to, cap, flow; Edge () {} Edge (intFromintTo,intCapintFlow): From, to, Cap (CAP), flow (flow) {}};structISAP {intP[n], Num[n], cur[n], d[n];intT, S, N, M;BOOLVis[n]; vector<int>G[n]; vector<Edge>EdgesvoidInitintN) { This->n = n; for(inti =0; I <= N; i++) {g[i].clear (); D[i] = INF; } edges.clear (); }voidAddedge (intFromintTo,intCAP) {Edges.push_back (Edge (from, to, Cap,0)); Edges.push_back (Edge (to, from,0,0)); m = Edges.size (); G[from].push_back (M-2); G[to].push_back (M-1); }BOOLBFS () {memset(Vis,0,sizeof(VIS)); Queue<int>Q; D[T] =0; VIS[T] =1; Q.push (t); while(! Q.empty ()) {intU = Q.front (); Q.pop (); for(inti =0; I < g[u].size (); i++) {Edge &e = edges[g[u][i] ^1];if(!vis[e.from] && e.cap > E.flow) {Vis[e.from] =true; D[e.from] = D[u] +1; Q.push (E.from); } } }returnVis[s]; }intAugment () {intU = T, flow = INF; while(U! = s) {Edge &e = edges[p[u]]; flow = min (flow, e.cap-e.flow); u = edges[p[u]].from; } u = t; while(U! = s) {Edges[p[u]].flow + = flow; Edges[p[u] ^1].flow-= flow; u = edges[p[u]].from; }returnFlow }intMaxflow (intSintT) { This->s = s; This->t = t;intFlow =0; BFS ();if(D[s] >= N)return 0;memset(Num,0,sizeof(num));memset(cur,0,sizeof(cur)); for(inti =0; I < n; i++)if(D[i] < INF) num[d[i]]++;intU = s; while(D[s] < n) {if(U = = t) {Flow + = Augment (); U = s; }BOOLOK =false; for(inti = Cur[u]; I < g[u].size (); i++) {Edge &e = edges[g[u][i]];if(E.cap > E.flow && d[u] = = D[e.to] +1) {OK =true; P[e.to] = G[u][i]; Cur[u] = i; u = e.to; Break; } }if(!ok) {intMin = N-1; for(inti =0; I < g[u].size (); i++) {Edge &e = edges[g[u][i]];if(E.cap > E.flow) min = min (min, d[e.to]); }if(--num[d[u]] = =0) Break; Num[d[u] = Min +1]++; Cur[u] =0;if(U! = s) u = edges[p[u]].from; } }returnFlow }};isap ISAP;#define M 100010intD1[n], D2[n], N, M, S, T, CNT;intHead[n], next[m], dis[m], to[m];BOOLVis[n];voidSPFA (intSint*D) { for(inti =1; I <= N; i++) {D[i] = INF; Vis[i] =0; } D[s] =0; Queue<int>Q Q.push (s); while(!q.empty ()) {intU = Q.front (); Q.pop (); Vis[u] =false; for(inti = Head[u]; I! =-1; i = Next[i]) {intv = to[i];if(D[v] > D[u] + dis[i]) {D[v] = D[u] + dis[i];if(!vis[v]) {Vis[v] =true; Q.push (v); } } } }}voidAdd_edges (intUintVintd) {to[cnt] = V; DIS[CNT] = D; NEXT[CNT] = Head[u]; Head[u] = cnt++;}structNode {intX, Y, Z;} NODE[M];voidSolve () {scanf("%d%d", &n, &m); CNT =0;memset(Head,-1,sizeof(head));intX, y, Z; for(inti =0; I < m; i++) {scanf("%d%d%d", &x, &y, &z); node[i].x = x; Node[i].y = y; Node[i].z = Z;if(x = = y)Continue; Add_edges (y, x, z); }scanf("%d%d", &s, &t); SPFA (T, D2); CNT =0;memset(Head,-1,sizeof(head)); for(inti =0; I < m; i++) {if(node[i].x = = node[i].y)Continue; Add_edges (node[i].x, Node[i].y, node[i].z); } SPFA (S, D1); Isap.init (n); for(inti =1; I <= N; i++) for(intj = Head[i]; J! =-1; j = Next[j]) {intv = to[j];if(D1[i] + dis[j] + d2[v] = = D1[t]) {Isap. Addedge (i, V,1); } }printf("%d\n", Isap. Maxflow (S, t));}intMain () {intTestscanf("%d", &test); while(test--) {Solve (); }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU-3416 marriage Match IV (Max Stream)