Dinic极品优化

#ifdef ONLINE_JUDGE 
#else 
#define Qiu_Cheng 
#endif 
#include <bits/stdc++.h> 
#define int long long 
using namespace std; 
// typedef long long ll; 
const int N=3e5+5,mod=1e9+7,inf=INT_MAX; 
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118; 
// const int M=mod1*mod2;
inline int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
    return x*f;
}
inline void write(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
int n,m,S,T;
int dep[N],pos[N];
struct edge
{
    int u,v,w;
};
struct node
{
    int to,c,lp,is;
};
vector<node>g[N];
void add(int from,int to,int c)
{
    g[from].push_back((node){to,c,(int)g[to].size()});
    g[to].push_back((node){from,0,(int)g[from].size()-1});
}
void fc(int s)
{
    for(int i=1;i<=n;i++) dep[i]=-1;
    queue<int>q;
    dep[s]=0;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(auto v:g[u])
        {
            if(v.c>0&&v.is&&dep[v.to]<0)
            {
                dep[v.to]=dep[u]+1;
                q.push(v.to);
            }
        }
    }
}
int dfs(int u,int t,int f)
{
    if(u==t||!f) return f;
    int ans=0;
    for(int &i=pos[u];i<g[u].size();i++)
    {
        auto &x=g[u][i];
        if(dep[u]+1==dep[x.to]&&x.is&&x.c>0)
        {
            int res=dfs(x.to,t,min(f,x.c));
            if(res>0)
            {
                x.c-=res;g[x.to][x.lp].c+=res;
                f-=res;ans+=res;
                if(!f) break;
            }
        }
    }
    return ans;
}
int max_flow=0;
int dinic(int s,int t)
{
    int flow=0;
    while(1)
    {
        fc(s);
        if(dep[t]==-1) return flow;
        for(int i=1;i<=n;i++) pos[i]=0;
        flow+=dfs(s,t,inf);
    }
}
int frz[N];//存一下from在to中的位置信息
edge a[N]; 
inline void solve()
{
    n=read();m=read();S=read();T=read();
    for(int i=1;i<=m;i++)
    {
        a[i].u=read();a[i].v=read();a[i].w=read();
        // cin>>a[i].u>>a[i].v>>a[i].w;
    }
    for(int i=30;i>=0;i--)
    {
        int p=(1<<i);//分段操作
        for(int j=1;j<=m;j++) 
        {
            if(a[j].w>=p&&a[j].w<(p<<1)) 
            {
                add(a[j].u,a[j].v,a[j].w);
                frz[j]=g[a[j].v].size()-1;
                g[a[j].u][g[a[j].u].size()-1].is=1;//先跑正
            }
        }
        max_flow+=dinic(S,T);
    }
    for(int i=30;i>=0;i--)
    {
        int p=(1<<i);
        for(int j=1;j<=m;j++) 
        {
            if(a[j].w>=p&&a[j].w<(p<<1)) 
            {
                g[a[j].v][frz[j]].is=1;//再跑反
            }
        }
        max_flow+=dinic(S,T);
    }
    write(max_flow);
}
signed main() 
{ 
#ifdef Qiu_Cheng 
    freopen("1.in","r",stdin); 
    freopen("1.out","w",stdout); 
#endif 
    // ios::sync_with_stdio(false); 
    // cin.tie(0); cout.tie(0); 
    // int QwQ; 
    // cin>>QwQ; 
    // while(QwQ--)solve(); 
    solve(); 
    return 0; 
}
//12 825076913 0 173167432
//  6666   66666  666666 
// 6    6  6   6      6 
// 6    6  6666      6 
// 6    6  6  6    6 
//  6666   6   6  6666666

//g++ -O2 -std=c++14 -Wall "-Wl,--stack= 536870912 " cao.cpp -o cao.exe
posted @ 2025-01-01 21:31  Nightmares_oi  阅读(2)  评论(0编辑  收藏  举报