Luo Gu P4126 [AHOI2009] minimum cut

Title: Luo Gu P4126 [AHOI2009] minimum cut

Ideas:

Conclusions title

The residue was run on a network to obtain tarjan all SCC, denoted id [u] SCC numbered point u lies. Obviously there are id [s]! = Id [ t] ( t or s to have access, to continue augmented).
For any one full flow edge (u, v), (u , v) can be present in a certain minimum concentration cut, if and only id [u] = id [v ];!
For any one full flow edge (u, v), (u, v) must appear in the minimum cut set, if and only id [u] == id [s ] and id [v] == id [t ].

It proved that:
① SCC shrunk to a point each, to obtain a new map on the side containing only full flow. Then a new map any st cut picture corresponds to a minimum cut, which either take a the id [u] and id [v] can cut the cut proof.
② assumed increased (u, v) of the right side, then the residue occurs in the network s-> u-> v-> t of the passage, so that it can continue augmented, then the maximum flow rate of the flow (i.e. a minimum capacity cut) It will increase. This explanation i.e. (u, v) is the minimum concentration cutting edge must be present.

The above explanation has been relatively clear, limited thinking, not think of a better interpretation, therefore not too much to explain.
Note that the remaining amount of the code refers to the actual network shown in FIG construction, after the finish all the edge weights greater than the maximum flow of edges in the configuration 0 in which there is a reverse arc.


Code:

#include <bits/stdc++.h>
using namespace std;
const int N=5e5+5,inf=0x3f3f3f3f;
int n,m,s,t,d[N];
int tim,tp,scc_num,st[N],dfn[N],low[N],belong[N];
int Top=1,ver[N],val[N],nxt[N],head[N];
inline void add(int u,int v,int w){
    ver[++Top]=v;val[Top]=w;nxt[Top]=head[u];head[u]=Top;
    ver[++Top]=u;val[Top]=0;nxt[Top]=head[v];head[v]=Top;
}
bool bfs(){
    for(int i=1;i<=n;++i) d[i]=0;
    queue<int> q;
    q.push(s);
    d[s]=1;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i;i=nxt[i]){
            int v=ver[i];
            if(val[i]&&!d[v]){
                d[v]=d[u]+1;
                if(v==t) return true;
                q.push(v);
            }
        }
    }
    return false;
}
int dfs(int u,int flow){
    if(u==t) return flow;
    int left=flow;
    for(int i=head[u];i&&left;i=nxt[i]){
        int v=ver[i];
        if(val[i]&&d[v]==d[u]+1){
            int res=dfs(v,min(left,val[i]));
            if(!res) d[v]=0;
            val[i]-=res;
            val[i^1]+=res;
            left-=res;
        }
    }
    return flow-left;
}
void tarjan(int u){
    dfn[u]=low[u]=++tim;
    st[++tp]=u;
    for(int i=head[u];i;i=nxt[i]){
        int v=ver[i];
        if(!val[i]) continue;//注意此处 在残量网络中tarjan 
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!belong[v]) low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u]){
        ++scc_num;
        int t;
        do{
            t=st[tp--];
            belong[t]=scc_num;
        } while(t!=u);
    }
}
int main(){
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1,u,v,w;i<=m;++i){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
    }
    while(bfs()) dfs(s,inf);
    for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i);
    for(int i=2;i<=Top;i+=2){
        int u=ver[i^1],v=ver[i];
        if(!val[i]&&belong[u]!=belong[v]) printf("%d ",1);
        else printf("%d ",0);
        if(!val[i]&&belong[u]==belong[s]&&belong[v]==belong[t]) printf("%d",1);
        else printf("%d",0);
        putchar('\n');
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/yu-xing/p/11323872.html