"BZOJ-2229" min Cut minimum cut tree (max flow + divide rule)

Source: Internet
Author: User

2229: [Zjoi2011] min cut time limit:10 Sec Memory limit:259 MB
submit:1565 solved:560
[Submit] [Status] [Discuss] Description

Small white in the graph theory class to learn a new concept-the minimum cut, after class, the small white in the notebook wrote down the following paragraph: "For a graph, a graph of the nodes in the diagram of the division of all the nodes are divided into two parts, if the node s,t is not in the same section, it is said that the division is about S,t. For a weighted graph, the value obtained by adding the weights of the edges of all vertices in different parts is defined as the capacity of the cut, while the minimum cut of s,t refers to the smallest cut in the cut of the s,t "now given an no-map, small white has a number of shapes such as" how many pairs of points in the figure of their minimum cut capacity not more than x? " The doubt, small blue although very want to answer these questions, but little blue recently busy digging wood, so as is still small blue friends, you have a task.

Input

The first line of the input file has only a positive integer t, which represents the number of groups of test data. For each set of test data, the first row contains two integer n,m, which represents the number of points and sides of a graph. The following m line, 3 positive integers per line u,v,c (1<=u,v<=n,0<=c<=106), indicates that there is a non-facing edge (U,V) with a right of c the next line, containing an integer q, which indicates the number of queries below the Q line, an integer x per line, with the meaning of the topic described.

Output

For each set of test data, the output should include the Q line, and line I indicates the answer to question I. For point Pairs (p,q) and (q,p), only one time is counted (see example).

Two sets of test data are separated by a blank line.

Sample Input1
5 0
1
0
Sample Output10

"Data Range"
The data t<=10,n<=150,m<=3000,q<=30,x for 100% is within the range of a 32-bit signed integer type.
There may be more than one edge between two points in the diagram
Hintsource

Day1

Solution

The smallest cut tree gomory-hu trees, a total of n-1 a minimum cut, connected together, forming a tree, concrete see below

The Gomory-hu tree is the smallest cut that represents all the nodes in the source mesh. The maximum flow (maximum flow minimum cut theorem) between 22 node pairs can be understood by solving the gomory-hu tree. Example:

The left side is an gomory-hutree graph, and the right side is the initial (a bit in the uniform set), and the Gomory-hu tree is solved below.

Step one: Arbitrarily select a source node and a destination node. In this example, the general Selection Node 1 is the source node (s), and 5 is the destination node (t). The maximum flow is 6, and the minimum cut is divided into two sets as shown on the right.

Step two: Arbitrarily select a source node and a destination node that are different from the previous step. In this example, the general Selection node 3 is the source node (s), and 5 is the destination node (t). Since 1244 nodes are considered to be a collection, the maximum flow is 8 and the minimum cut is divided into three sets as shown on the right.

Step three: Arbitrarily select a source node and a destination node that are different from the previous step. In this example, the general Selection Node 1 is the source node (s), and 2 is the destination node (t). The maximum flow is 6, and the minimum cut is divided into four sets as shown on the right.

Repeat the above steps to divide the original graph into a gomory-hutree, as shown in.

Through this solution process, the code implementation of the entire step is very complex. 1990 Dan Gusfield presents an easy-to-implement Gomory-hutree solution through the "Very simple Methods for all Pairs Network Flow analysis" article, which is also the implementation method in this paper. Here's an example of how this can be done:

Without loss of generality, an example of the original image is a 6-node graph, the weights between the nodes are 1, the smallest cut between nodes as shown:

Step one: Create a star tree, node 1 is the central node, the other nodes are leaf nodes, as shown on the left.

Step two: Select the nodes numbered 2 to 6 respectively as the source node (s), repeat steps three and four.

Step three: In the star tree to make the node adjacent to the S node as the destination node (t), calculate the maximum flow between S and T, and thus get the minimum cut. The maximum flow is labeled on the link between the S node and the T node in the Star tree.

Step four: For each node with a number greater than S, if the original s and I are neighbors, and I and s in the same cut set, then remove the star map I and T connection, increase I and s of the connection, as shown in the middle.

Finally, you can get the Gomory-hutree as shown on the right.

Similarly, according to the above practice, can be recursive division of the request, the final statistical answer can be

The specific implementation:

For each layer of division, the first choice of two points as a Yuanhui to do the minimum cut
Then find the S-set and T-sets, the point pairs of all S-sets of points and T-sets are updated with the smallest cut of this time
Then divide the points of this division into S-sets and T-sets, and treat two sets of

Notable places:

1. Because it is a non-directed graph, the edge of the time can be directly two in one, so that convenient division of the time, restore capacity

2. When divided, l,r control, attention to initialization, do not miss

3. Note that the initial $s$ set and the original $t$ set are required to be updated, not only the $s ' $ set and $t ' $ sets within this division

Code
#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespacestd;intRead () {intx=0, f=1;CharCh=GetChar ();  while(ch<'0'|| Ch>'9'){if(ch=='-') f=-1; ch=GetChar ();}  while(ch>='0'&&ch<='9') {x=x*Ten+ch-'0'; ch=GetChar ();} returnx*F;}#defineMAXN 200#defineMAXM 100010intN,M,Q,T,ANS[MAXN][MAXN],ID[MAXN],TMP[MAXN];structedgenode{intNext,to,cap;} EDGE[MAXM];intHead[maxn],cnt=1;voidAddintUintVintW) {CNT++; Edge[cnt].to=v; Edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].cap=W;}voidInsertintUintVintW) {Add (u,v,w); add (v,u,w);}intdis[maxn],que[maxn<<1],cur[maxn],s,t;BOOLBFs () {memset (DIS,-1,sizeof(DIS)); que[0]=s; dis[s]=0;intHe=0, Ta=1;  while(he<ta) {            intnow=que[he++];  for(intI=head[now]; I I=edge[i].next)if(Edge[i].cap && dis[edge[i].to]==-1) dis[edge[i].to]=dis[now]+1, que[ta++]=edge[i].to; }    returndis[t]!=-1;}intDfsintLocintLow ) {    if(loc==t)returnLow ; intW,used=0;  for(intI=cur[loc]; I I=edge[i].next)if(Edge[i].cap && dis[edge[i].to]==dis[loc]+1) {W=dfs (Edge[i].to,min (low-used,edge[i].cap)); Edge[i].cap-=w; edge[i^1].cap+=W; Used+=w;if(EDGE[I].CAP) cur[loc]=i; if(Used==low)returnLow ; }    if(!used) dis[loc]=-1; returnused;}#defineINF 0x7fffffffintDinic () {inttmp=0;  while(BFS ()) { for(intI=1; i<=n; i++) cur[i]=Head[i]; TMP+=DFS (S,inf); }    returntmp;}voidinit () {CNT=1; memset (ans,127,sizeof(ans)); memset (Head,0,sizeof(head));}BOOLVISIT[MAXN];voidDFS (intx) {Visit[x]=1;  for(intI=HEAD[X]; I I=edge[i].next)if(Edge[i].cap &&!)Visit[edge[i].to]) DFS (edge[i].to);}voidWorkintLintR) {    if(L==R)return;  for(intI=2; i<=cnt; i+=2) Edge[i].cap=edge[i^1].cap= (edge[i].cap+edge[i^1].CAP) >>1; S=id[l],t=Id[r]; intmaxflow=Dinic (); memset (Visit,0,sizeof(visit));    DFS (S);  for(intI=1; i<=n; i++)if(Visit[i]) for(intj=1; j<=n; J + +)if(!Visit[j]) ans[i][j]=ans[j][i]=min (ans[i][j],maxflow); intL=l,r=s;  for(intI=l; i<=r; i++)        if(Visit[id[i]]) tmp[l++]=Id[i]; Elsetmp[r--]=Id[i];  for(intI=l; i<=r; i++) id[i]=Tmp[i]; Work (L,l-1); Work (r+1, R);} intMain () {//freopen ("mincuto.in", "R", stdin);//freopen ("Mincuto.out", "w", stdout);t=read ();  while(t--) {init (); N=read (), m=read ();  for(intI=1; i<=n; i++) id[i]=i;  for(intU,v,w,i=1; i<=m; i++) U=read (), V=read (), w=read (), insert (U,V,W); Work (1, N); Q=read ();  for(intC,i=1; i<=q; i++) {C=read ();intan=0;  for(intj=1; j<=n; J + +)                         for(intk=j+1; k<=n; k++)                            if(ans[j][k]<=c) an++; printf ("%d\n", an); } puts (""); }    return 0;}

"BZOJ-2229" min Cut minimum cut tree (max flow + divide rule)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.