Available from the previous article
The weight of the largest weight closed graph is sum-max_flow
Sum is the sum of values, and max_flow is the largest stream after the graph is re-created.
After finding the maximum stream, all the points searched by DFS from S in the residual network are the points in the max weight closed graph. That is, the minimum cut corresponds to the max weight closed graph.
View code
# Include <stdio. h>
# Include < String . H>
Const Int Max = 100005 ;
Const Int INF = 1000000000 ;
Struct
{
Int V, C, next;
} Edge [ 1000000 ];
Int E, head [Max];
Int Gap [Max], cur [Max];
Int Pre [Max], DIS [Max];
Void Add_edge ( Int S, Int T, Int C, Int CC)
{
/* When adding an edge, add two at the same time,
One is positive, one is opposite,
Generally, the reverse capacity is 0. */
Edge [e]. V = T; edge [e]. C = C;
Edge [e]. Next = head [s];
Head [s] = e ++;
Edge [e]. V = s; edge [e]. c = cc;
Edge [e]. Next = head [T];
Head [T] = e ++;
}
Int Min ( Int A, Int B ){ Return (A =- 1 | B <)? B: ;}
_ Int64 SAP ( Int S, Int T, Int N)
{
Memset (gap, 0 , Sizeof (GAP ));
Memset (DIS, 0 , Sizeof (DIS ));
Int I;
For (I = 0 ; I <n; I ++) cur [I] = head [I];
Int U = pre [s] = s, Aug =- 1 , V;
_ Int64 maxflow = 0 ;
Gap [ 0 ] = N;
While (DIS [s] <n)
{
Loop: For (I = cur [u]; I! =- 1 ; I = edge [I]. Next)
{
V = edge [I]. V;
If (Edge [I]. c> 0 & Dis [u] = dis [v] + 1 )
{
Aug = min (Aug, edge [I]. C );
Pre [v] = u;
Cur [u] = I;
U = V;
If (U = T)
{
For (U = pre [u]; V! = S; V = u, u = pre [u])
{
Edge [cur [u]. C-= Aug;
Edge [cur [u] ^ 1 ]. C ++ = Aug;
}
Maxflow + = Aug;
Aug =- 1 ;
}
Goto Loop;
}
}
Int Mindis = N;
For (I = head [u]; I! =- 1 ; I = edge [I]. Next)
{
V = edge [I]. V;
If (Edge [I]. c> 0 & Dis [v] <mindis)
{
Cur [u] = I;
Mindis = dis [v];
}
}
If (-- Gap [dis [u]) = 0 ) Break ;
Gap [dis [u] = mindis + 1 ] ++;
U = pre [u];
}
Return Maxflow;
}
Bool Vis [Max];
Void DFS ( Int U, Int T)
{
If (U = T) Return ;
Vis [u] = True ;
For ( Int I = head [u]; I! =- 1 ; I = edge [I]. Next)
If (Edge [I]. c> 0 &&! Vis [edge [I]. V])
DFS (edge [I]. V, t );
}
Int Main ()
{
Int I, n, m, J, W, A, B;
Scanf ( " % D " , & N, & M );
_ Int64 sum = 0 ;
Int S = 0 , T = n + 1 ;
Memset (Head ,-1 , Sizeof (Head); E = 0 ;
For (I = 1 ; I <= N; I ++)
{
Scanf ( " % D " , & W );
If (W> 0 )
{Sum + = W;
Add_edge (S, I, W, 0 );
}
Else Add_edge (I, T,-W, 0 );
}
While (M --)
{
Scanf ( " % D " , & A, & B );
Add_edge (a, B, INF, 0 );
}
_ Int64 mxflow = SAP (S, T, N + 2 );
Memset (VIS,0 , Sizeof (VIS ));
DFS (S, T ); Int Ans = 0 ;
For (I = 1 ; I <= N; I ++)
{
If (Vis [I])
Ans ++;
}
Printf ( " % D % i64d \ n " , ANS, Sum-mxflow );
Return 0 ;
}