Minimum cut tree (Luo Gu 4897)

Minimum cut tree

Minimum cut requirements between any two points

Every time the current focus point sources and sinks as uv any two running minimum cut, the right cut edge is smallest between a uv even, then divided according to a set down to do

Minimum = minimum cut between two points on the right side of the new path in FIG.

code

Still in tune

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define inf 2133333333
using namespace std;

int aa[1111][3];
int Ls[512];
int a[3102][3];
int A[3102];
int ls[512];
int cur[512];
int f[512];
int g[512];
int d[512][512];
int b[512];
int bz[512];
int d2[512];
int fa[512][9];
int mn[512][9];
int D[512];
int Q,n,m,i,j,k,l,len,st,ed,Len,h2,t2,x,y;

void New(int x,int y,int z)
{
    ++len;
    a[len][0]=y;
    a[len][1]=ls[x];
    ls[x]=len;
    a[len][2]=A[len]=z;
}

void NEW(int x,int y,int z)
{
    ++Len;
    aa[Len][0]=y;
    aa[Len][1]=Ls[x];
    Ls[x]=Len;
    aa[Len][2]=z;
}

int dfs(int t,int flow)
{
    int i,use=0;
    
    if (t==ed)
    return flow;
    
    for (i=cur[t]; i; i=a[i][1])
    {
        cur[t]=i;
        
        if (f[t]==f[a[i][0]]+1 && a[i][2])
        {
            int w=dfs(a[i][0],min(flow-use,A[i]));
            
            a[i][2]+=w;
            a[i^1][2]-=w;
            use+=w;
            
            if (use==flow)
            return use;
        }
    }
    cur[t]=ls[t];
    
    --g[f[t]];
    if (!g[f[t]])
    {
        f[st]=n+1;
        return use;
    }
    ++f[t];++g[f[t]];
    
    return use;
}

void work(int t)
{
    int Ans=0;
    
    if (b[t]<=1)
    return;
    
    memset(f,0,sizeof(f));
    memset(g,0,sizeof(g));
    fo(i,1,len) a[i][2]=A[i];
    
    g[0]=n;
    st=d[t][1];
    ed=d[t][2];
    
    while (f[st]<=n)
    Ans+=dfs(st,inf);
    
    NEW(st,ed,Ans);
    NEW(ed,st,Ans);
    
    b[t+1]=1;
    d[t+1][1]=st;
    bz[st]=t+1;
    
    h2=0;t2=1;
    d2[1]=st;
    while (h2<t2)
    {
        for (i=ls[d2[++h2]]; i; i=a[i][1])
        if (a[i][2] && a[i^1][2] && bz[a[i][0]]==t)
        {
            d2[++t2]=a[i][0];
            bz[a[i][0]]=t+1;
            
            d[t+1][++b[t+1]]=a[i][0];
        }
    }
    work(t+1);
    
    b[t+1]=0;
    fo(i,1,b[t])
    if (bz[d[t][i]]==t+1)
    bz[d[t][i]]=t;
    else
    if (bz[d[t][i]]==t)
    {
        d[t+1][++b[t+1]]=d[t][i];
        bz[d[t][i]]=t+1;
    }
    
    work(t+1);
    fo(i,1,b[t])
    if (bz[d[t][i]]==t+1)
    bz[d[t][i]]=t;
}

void swap(int &x,int &y)
{
    int z=x;
    x=y;
    y=z;
}

int js(int x,int y)
{
    int i,ans=inf;
    
    if (D[x]<D[y])
    swap(x,y);
    
    fd(i,8,0)
    if (D[fa[x][i]]>=D[y])
    ans=min(ans,mn[x][i]),x=fa[x][i];
    
    fd(i,8,0)
    if (fa[x][i]!=fa[y][i])
    ans=min(ans,min(mn[x][i],mn[y][i])),x=fa[x][i],y=fa[y][i];
    
    if (x!=y) ans=min(ans,min(mn[x][0],mn[y][0]));
    return ans;
}

void Dfs(int Fa,int t)
{
    int i;
    
    fa[t][0]=Fa;
    D[t]=D[Fa]+1;
    fo(i,1,8)
    fa[t][i]=fa[fa[t][i-1]][i-1],mn[t][i]=min(mn[t][i-1],mn[fa[t][i-1]][i-1]);
    
    for (i=Ls[t]; i; i=aa[i][1])
    if (aa[i][0]!=Fa)
    {
        mn[aa[i][0]][0]=aa[i][2];
        Dfs(t,aa[i][0]);
    }
}

int main()
{
//  freopen("luogu4897.in","r",stdin);
    
    scanf("%d%d",&n,&m);len=1;++n;
    fo(i,1,m)
    {
        scanf("%d%d%d",&j,&k,&l);
        ++j;++k;
        
        New(j,k,l);
        New(k,j,l);
    }
    
    b[0]=n;
    fo(i,1,n)
    d[0][i]=i;
    return 0;
    work(0);
    Dfs(0,1);
    
    scanf("%d",&Q);
    for (;Q;--Q)
    {
        scanf("%d%d",&x,&y);++x;++y;
        printf("%d\n",js(x,y));
    }
}

Guess you like

Origin www.cnblogs.com/gmh77/p/12089135.html