Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=5294
Problem descriptioninnocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu's at the entrance of the tomb while Dumb Zhang's at the end of it. The tomb is made up of many chambers, and the total number is N. And there is M channels connecting the chambers. Innocent Wu wants to catch up Dumb-to-find out the answers of some questions, however, it ' s Dumb Zhang ' s intention t o Keep Innocent Wu in the dark, to do which he have to stop Innocent Wu from getting him. Only via the original shortest ways from the entrance to the end of the tomb costs the minimum time, and that's the only C Hance Innocent Wu can catch Dumb Zhang.
Unfortunately, Dumb Zhang masters The Art of becoming invisible (qi men dun jia) and tricks devices of this tomb, he can cut off the Connections between chambers by using them. Dumb Zhang wanders how many channels at least he had to cut to stop Innocent Wu. And Innocent Wu wants to know after what many channels at most Dumb Zhang cut off Innocent Wu still have the chance to catch Dumb Zhang.
Inputthere is multiple test cases. Please process till EOF.
For each case,the first line must includes the integers, N (<=2000), M (<=60000). N is the total number of the chambers, and M is the total number of the channels.
In the following M lines, every line must includes three numbers, and use AI, Bi, Li as channel i connecting Chamber AI and Bi (1<=ai,bi<=n), it costs Li (0<li<=100) minute to pass channel I.
The entrance of the tomb is at the chamber one, and the end of tomb is at the chamber N.
Outputoutput numbers to stand for the answers of Dumb Zhang and Innocent Wu ' s questions.
Sample Input
8 91 2 22 3 22 4 13 5 34 5 45 8 11 6 26 7 57 8 1
Sample Output
2 6
Authorfzuacm
Source2015 multi-university Training Contest 1
Turn
Test instructions
Give the n tomb, M path, a person in the Tomb No. 1th (beginning), another person in the tomb of N (end);
The person at the beginning can only catch up with the shortest path to the end of the person, and the end of the person to cut off any path.
The first question--the end of the person to make the starting point that the person can not catch up the number of paths to be cut, the minimum number of paths to output
The second question--the beginning that man can catch up with the end of the person's case, the end that person can cut the maximum number of paths, output the maximum number of paths
PS:
Run the shortest way first.
Then through dist[i]-dist[j] = = Map[j][i]
If compliant, Map[j][i] is an edge in the shortest path.
Then the shortest side of the building map, run the maximum flow, the flow is how many sides of the same weight edge, run out is the smallest cut, that is, the minimum cost of blocking all the shortest. The cost is each destruction a road for 1. So the value out is the amount of damage to the edge.
And then the same as the maximum flow of the same building, run the shortest way, Edge 1, run out of the shortest road dist[n], is the smallest number of edges across the number of short-circuiting.
Official:
The code is as follows:
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <iostream > #include <algorithm>using namespace std; #define INF 0x3f3f3f3f#define MAXN 800047//The maximum number of points # # MAXM 2247// The maximum value of the number of sides int HEAD[MAXM], pre[maxm];int DEP[MAXM], CUR[MAXM], gap[maxm];//gap[x]=y: Indicates that the number of dep[i]==x in the residual network is Yint en;struct edge{int to,next,cap,flow;} EDGE[MAXN]; Note is Maxmint Tol;int K, C, M;int S, e;//source point, Meeting Point int map[maxm][maxm];int COST1[MAXM][MAXM], Cost2[maxm][maxm];int num[MAXM][ maxm];//record the number of edges, >1 both heavy edge//plus edge, one-way figure three parameters, bidirectional figure four parameters void Addedge (int u,int v,int w,int rw = 0) {edge[tol].to = 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];//input parameter: The number of the start, end point, number of points//points is not affected, as long as the total number of input points 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; while (Dep[start] < N) {if (U = = end) {int Min = INF; int inser; for (int 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 (int 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 (int 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 (int i = head[u]; i =-1; i = edge[i].next) if (Edge[i].cap-edge[i].flow && dep[edge[i].to] < M IN) {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; void Dijkstra (int s, int n, int cost[][maxm], int dis[maxm]) {//int dis[maxm];//records to any point of the mostShort distance int mark[maxm];//record the selected node int i, j, K; for (i = 1; I <= n; i++) {Mark[i] = 0;//Initializes all nodes, each node is not selected dis[i] = INF; } Mark[s] = 1;//start node is selected dis[s] = 0;//Sets the distance of the start node to 0 int min;//to set the shortest distance. for (i = 1; I <= n; i++) {k = 1;//The initial value is important MIN = INF; for (j = 1; J <= N; j + +) {if (!mark[j] && dis[j] < MIN)//unselected node, shortest distance is selected { MIN = Dis[j]; K = J; }} Mark[k] = 1;//marked as selected for (j = 1; J <= N; j + +) {if (!mark[j] && dis[j] >DIS[K] + cost[k][j])//Modify the minimum distance of remaining nodes {dis[j] = Dis[k] + cost[k][j]; }}}}void init () {memset (head,-1,sizeof (head)); memset (cost1,inf,sizeof (Cost1)); memset (cost2,inf,sizeof (Cost2)); memset (num,0,sizeof (num)); EN = 0;} int main () {int n, m; int U, V, W; int DIS1[MAXM], DIS2[MAXM]; while (~SCANF ("%d%d", & n,&m)) {init (); for (int i = 1; I <= n; i++) {cost1[i][i] = 0; } for (int i = 1; I <= m; i++) {scanf ("%d%d%d", &u,&v,&w); if (Cost1[u][v] > W) {cost1[u][v] = W; Cost1[v][u] = W; NUM[U][V] = 1; Num[v][u] = 1; } else if (cost1[u][v] = = W)//heavy side {num[u][v]++; num[v][u]++; }} Dijkstra (1,N,COST1,DIS1); for (int i = 1; I <= n; i++) {cost2[i][i] = 0; } for (int i = 1, i <= N; i++) {for (int j = 1; J <= N; j + +) {if ( I! = j) {if (Dis1[i]-dis1[j] = = Cost1[i][j])//Shortest side { Cost2[j][i] = 1; Addedge (J,i,num[i][j]); } } }} Dijkstra (1,N,COST2,DIS2); printf ("%d%d\n", SAP (1,N,N), m-dis2[n]); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 5294 Tricks Device (Multi-school 2015 Max Stream + Shortest path AH)