Harry Potter and the Forbidden Forest
Time limit:5000/3000 MS (java/others) Memory limit:65536/65536 K (java/others)
Total submission (s): 1791 Accepted Submission (s): 596
Problem Description Harry Potter notices some Death Eaters try to slip into Castle. The Death Eaters hide in the depths of Forbidden Forest. Harry need stop them as soon as.
The Forbidden Forest is mysterious. It consists of N nodes numbered from 0 to N-1. All of Death Eaters stay in the node numbered 0. The position of Castle is node n-1. The nodes connected by some roads. Harry need block some roads by magic and he want to minimize the cost. But it's not enough, Harry want to know how many roads is blocked at least.
Input input consists of several test cases.
The first line was number of test case.
Each test case, the first line contains the integers n, m, which means the number of nodes and edges of the graph. Each node was numbered 0 to n-1.
Following m lines contains information about edges. Each of the line have four integers u, V, C, D. The first and integers mean and endpoints of the edges. The third one is cost of block the edge. The fourth one means directed (d = 0) or undirected (d = 1).
Technical specification
1.2 <= n <= 1000
2.0 <= m <= 100000
3.0 <= u, v <= n-1
4.0 < C <= 1000000
5.0 <= D <= 1
Output for each test case:
Output the case number and the answer of how many roads is blocked at least.
Sample Input
3 4 5 0 1 3 0 0 2 1 0 1 2 1 1 1 3 1 1 2 3 3 1 6 7 0 1 1 0 0 2 1 0 0 3 1 0 1 4 1 0 2 4 1 0 3 5 1 0 4 0 1 1 0 0 1 2 0 1 1 1 1 1 2 1 0 1 2 1 0 2 1 1 1
Sample Output
Case 1:3 Case 2:2 case 3:2
Author AMR @ whu
Source multi-university Training Contest 15-host by WHU
Idea: We know that the minimum cut is not unique, here we need to cut the minimum cutting edge, the better practice is:
The first type:
When building edges, each edge w = w * (E + 1) + 1;
This gets the maximum flow Maxflow/(e + 1), the minimum number of cut edges maxflow% (e + 1)
The reason is very simple, if the original two types of cutting edges are the smallest cut, then the maximum flow is calculated equal
But only the small number of sides is the smallest cut when the edge is transformed.
Multiplication (e+1) is to ensure that the number of edges is still the remainder of the stack, without affecting the results of the minimum cut
The second type:
When the maximum flow is reached, the edge of the graph is full, indicating that the edge is the minimum cut edge
Re-build, principle: the full-stream edge changes to a capacity of 1 edge, the edge of the non-full stream to the edge of the capacity INF (the changed edges are forward edges), and then the maximum flow is the answer
/* Max stream: SAP algorithm, the difference from ISAP is no preprocessing */#include <stdio.h> #include <string.h> #include <queue> #include <
Algorithm> using namespace std; #define CAPTYPE int const int MAXN = 1010; Total number of points const int MAXM = 400010;
Total number of edges const int INF = 1<<30;
struct edg{int to,next;
Captype Cap,flow;
} EDG[MAXM];
int EID,HEAD[MAXN]; int GAP[MAXN]; The number of points for each distance (or can be considered a height) int DIS[MAXN]; The shortest distance from each point to the end Enode int CUR[MAXN];
Cur[u] means that from the U point can flow through the cur[u] number side int PRE[MAXN];
void Init () {eid=0;
memset (head,-1,sizeof (head));
}//There are three parameters to the edge, 4 parameters void addedg (int u,int v,captype c,captype rc=0) with no forward edge {edg[eid].to=v; edg[eid].next=head[u]; Edg[eid].cap=c; edg[eid].flow=0;
head[u]=eid++; Edg[eid].to=u;
EDG[EID].NEXT=HEAD[V]; EDG[EID].CAP=RC; edg[eid].flow=0;
head[v]=eid++;
} captype maxflow_sap (int snode,int enode, int n) {//n is the total number of points including the source and sink points, this must be noted memset (Gap,0,sizeof (GAP));
memset (dis,0,sizeof (dis));
memcpy (cur,head,sizeof (head));
Pre[snode] =-1;Gap[0]=n; Captype ans=0;
Max Stream int U=snode;
while (dis[snode]<n) {//determines from SNode point there is no flow to the next adjacent point if (u==enode) {//Find a way to add flow captype min=inf;
int inser;
for (int i=pre[u]; i!=-1; i=pre[edg[i^1].to])//To find the maximum amount of traffic Min if (min>edg[i].cap-edg[i].flow) {
Min=edg[i].cap-edg[i].flow;
Inser=i;
} for (int i=pre[u]; i!=-1; i=pre[edg[i^1].to]) {edg[i].flow+=min; Edg[i^1].flow-=min;
Flow of the side that can be recycled} ans+=min;
u=edg[inser^1].to;
Continue } bool flag = FALSE;
It is possible to determine whether an int v can flow toward the neighboring point from the U point;
for (int i=cur[u]; i!=-1; i=edg[i].next) {v=edg[i].to;
if (edg[i].cap-edg[i].flow>0 && dis[u]==dis[v]+1) {flag=true;
Cur[u]=pre[v]=i;
Break
}} if (flag) {u=v; Continue
}//If a flow adjacent point is not found above, then the distance from the starting point U (which can also be considered a height) is the minimum distance of +1 int mind= n for the adjacent flow point;
for (int i=head[u]; i!=-1; i=edg[i].next) if (edg[i].cap-edg[i].flow>0 && mind>dis[edg[i].to]) {
MIND=DIS[EDG[I].TO];
Cur[u]=i;
} gap[dis[u]]--; if (gap[dis[u]]==0) return ans; When Dis[u] The point of this distance is gone, it is impossible to find an augmented stream path from the source point//Because there is only one distance from the sink point to the current point, the current point must pass from the source point to the sink point, but the current point is not able to find
To the point that can flow, then the inevitable flow of dis[u]=mind+1;//if a stream of adjacent points is found, the distance is the distance of the adjacent point +1, if not found, then the n+1 gap[dis[u]]++; if (U!=snode) u=edg[pre[u]^1].to;
Back one side} return ans;
} int main () {int t,_cas=0,n,m,u,v,c,d;
scanf ("%d", &t);
while (t--) {init ();
scanf ("%d%d", &n,&m);
int vs=0,vt=n-1;
for (int i=0; i<m; i++) {scanf ("%d%d%d%d", &u,&v,&c,&d);
ADDEDG (U,V,C); if (d) addedg (V,U,C);
} MAXFLOW_SAP (VS, VT, N); for (int i=0; i<eid; i++) if (edg[i].cap==edg[i].flow&&edg[i].cap) edg[i].flow=0,edg[
I].cap=1;
else if (edg[i].cap) Edg[i].flow=0,edg[i].cap=inf;
int Ans=maxflow_sap (VS, VT, N);
printf ("Case%d:%d\n", ++_cas,ans);
}
}