Ikki ' s Story i-road reconstruction
Time Limit: 2000MS |
|
Memory Limit: 131072K |
Total Submissions: 7491 |
|
Accepted: 2172 |
Description
Ikki is the king of a small Country–phoenix, Phoenix are so small that there are only one city that's responsible for the Production of daily goods, and uses the road network to transport the goods to the capital. Ikki finds that, the biggest problem in the country was that transportation speed is too slow.
Since Ikki was an ACM/ICPC contestant before, he realized the this, indeed, is a maximum flow problem. He coded a maximum flow program and found the answer. Not satisfied with the current status of the transportation speed, he wants to increase the transportation ability of the Nation. The method is relatively simple, Ikki'll reconstruct some roads in this transportation network, to make those roads AFFO RD higher capacity in transportation. But unfortunately, the country of Phoenix isn't so rich in GDP that there was only enough money to rebuild one road. Ikki wants to find such roads so if reconstructed, the total capacity of transportation would increase.
He thought this problem for a loooong time but cannot get it. So he gave the problem to Frkstyc and who puts it in the This POJ Monthly contest for your to solve. Can you solve it for Ikki?
Input
The input contains exactly one test case.
The first line of the test case contains the integers n, m (n ≤500, m ≤5,000) which Represents the number of cities and roads in the country, Phoenix, respectively.
M lines follow, each line contains three integers a, b, C, which means the There is a Road from City a to city b with a transportation capacity of C (0≤ a, b < n, c ≤100). All the roads is directed.
Cities is numbered from 0 to n − 1, the city which can product goods be numbered 0, and the capital is Numbere D N −1.
Output
You should output one line consisting of only one integer
K, denoting that there is
KRoads, reconstructing each of which would increase the network transportation capacity.
Sample Input
2 10 1 1
Sample Output
1
Test instructions: From source point 0 to meeting point N-1, ask those sides to increase capacity will increase the capacity of the entire network?? The number of output edges.
Here's an important concept: key edges, key edges defined as: increase the maximum flow of the network by increasing the capacity of an edge
The personal understanding of the minimum cut inside the edge must be the key cutting edge, but the key cutting edge is not necessarily the smallest cut.
The practice is to first seek the maximum flow, and then to the residual network two Dfs, from the source point of the DFS is simple, from the positive edge to the edge of the capacity of 0, to get a point set a, mark, mainly from the meeting point for the second DFS, here to use the technique, the network flow has a magical reverse edge, We do Dfs from the opposite side (also to determine if the forward edge is 0) to get the point set B, Mark, and then traverse all the edges, if the two endpoints of an edge belong to the point set, A, B, then this edge is definitely the key cutting edge, record it.
#include <stdio.h>#include<algorithm>#include<queue>#include<string.h>#include<math.h>#include<iostream>#include<math.h>using namespacestd;Const intN =505;Const intINF =999999999;structedge{intV,next; intW;} Edge[n*N];intHead[n];intLevel[n];inttot;voidinit () {memset (head,-1,sizeof(head)); Tot=0;}voidAddedge (intUintVintWint&k) {EDGE[K].V= v,edge[k].w=w,edge[k].next=head[u],head[u]=k++; EDGE[K].V= u,edge[k].w=0, edge[k].next=head[v],head[v]=k++;}intBFS (intSrcintdes) {Queue<int>Q; Memset (Level,0,sizeof(level)); LEVEL[SRC]=1; Q.push (SRC); while(!Q.empty ()) { intU =Q.front (); Q.pop (); if(U==des)return 1; for(intk = Head[u]; k!=-1; k=Edge[k].next) { intv =edge[k].v; intW =EDGE[K].W; if(level[v]==0&&w!=0) {Level[v]=level[u]+1; Q.push (v); } } } return-1;}intDfsintUintDesintincreaseroad) { if(U==des)returnIncreaseroad; intret=0; for(intK=head[u]; k!=-1; k=Edge[k].next) { intv =edge[k].v; intW =EDGE[K].W; if(level[v]==level[u]+1&&w!=0) { intmin = min (increaseroad-ret,w); W=DFS (v,des,min); if(w>0) {EDGE[K].W-=V; Edge[k^1].w+=W; RET+=W; if(Ret==increaseroad)returnret; } ElseLEVEL[V] =-1; } } returnret;}intDinic (intSrcintdes) { intAns =0; while(BFS (Src,des)!=-1) ans+=DFS (Src,des,inf); returnans;}intVis[n];voidDfs0 (intu) {Vis[u]=1; for(intK=head[u]; k!=-1; k=Edge[k].next) { intv = edge[k].v,w =EDGE[K].W; if(!vis[v]&&w>0) {dfs0 (v); } }}voidDFS1 (intu) {Vis[u]=2; for(intK=head[u]; k!=-1; k=Edge[k].next) { intv =edge[k].v; if(!vis[v]&&edge[k^1].w>0&&edge[k].w>0)///The meeting point uses the reverse edge to search, and here you have to determine whether the forward edge is greater than 0{DFS1 (v); } }}intMain () {intn,m; scanf ("%d%d",&n,&m); Init (); for(intI=0; i<m; i++) { intu,v,w; scanf ("%d%d%d",&u,&v,&W); if(U==V)Continue; Addedge (U,v,w,tot); } memset (Vis,0,sizeof(VIS)); Dinic (0, N-1); Dfs0 (0); DFS1 (n-1); intAns =0; for(intu=0; u<n; u++) { for(intK=head[u]; k!=-1; k=Edge[k].next) { if(k%2==1)Continue;///only the forward edges are considered if(vis[u]==1&&vis[edge[k].v]==2) ans++; }} printf ("%d\n", ans);}
Hdu 3204 (min. cut-Key cutting edges)