Dinic 70分TLE求助

P3376 【模板】网络最大流

chentianyi @ 2020-04-14 21:44:16

哪位大佬能帮忙看看怎么把时间减下去(我2、9、10 TLE)

//Dinic
#include<bits/stdc++.h>
using namespace std;
const int inf=1<<29,N=10001,M=100001;
int head[N],ver[M],edge[M],next[M],d[N],now[M];
int n,m,s,t,tot=1,maxflow;
queue<int>q;
void add(int x,int y,int z)
{
    ver[++tot]=y,edge[tot]=z,next[tot]=head[x],head[x]=tot;
    ver[++tot]=x,edge[tot]=0,next[tot]=head[y],head[y]=tot;//反向建边 
}
bool bfs()
{
    memset(d,0,sizeof(d));
    while(q.size()) q.pop();
    q.push(s);
    d[s]=1;
    now[s]=head[s];
    while(q.size())
    {
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=next[i])
        {
            int y=ver[i];
            if(edge[i]&&!d[y])
            {
                q.push(y);
                now[y]=head[y];
                d[y]=d[x]+1;
                if(y==t) return 1;
            }
        }
    }
    return 0;
}
int dinic(int x,int flow)
{
    if(x==t) return flow;
    int rest=flow,k,i;
    for(i=now[x];i&&rest;i=next[i])
    {
        int y=ver[i];
        if(edge[i]&&d[y]==d[x]+1)
        {
            k=dinic(y,min(rest,edge[i]));
            if(!k) d[y]=0;//剪枝
            edge[i]-=k;
            edge[i^1]+=k;
            rest-=k; 
        }
    }
    now[x]=i;
    return flow-rest;
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        int x,y,w;
        scanf("%d%d%d",&x,&y,&w);
        add(x,y,w);
    }
    int flow=0;
    while(bfs())
        while(flow=dinic(s,inf))
            maxflow+=flow;
    printf("%d",maxflow);
    return 0;
}

by lx_zjk @ 2020-04-14 21:53:42

弧优化


by chentianyi @ 2020-04-14 21:55:01

@Hock now数组已经弧优化过了啊


by lx_zjk @ 2020-04-14 21:57:15

inline int dfs (int u, int t, int limit) {
    if (!limit || u == t) return limit;
    int flow = 0;
    for (int &i = head[u], v, w, f; i; i = edge[i].next) {
        v = edge[i].to; w = edge[i].w;
        if (dep[v] == dep[u] + 1 && (f = dfs (v, t, min (limit, w))) > 0) {
            limit -= f; flow += f;
            edge[i].w -= f;
            edge[i ^ 1].w += f;
            if (!limit) break;
        }
    }
    return flow;
}

我的写法感觉跟您不一样


by chentianyi @ 2020-04-15 09:54:22

@Hock 调试了好长时间,现在过了,Thanks♪(・ω・)ノ


|