萌新求助 TLE 只有70

P3376 【模板】网络最大流

哔哩哔哩 @ 2018-12-23 00:11:31

刚接触dinic

不是很懂优化

求大佬帮忙

//Dinic
#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define INF 0x3fffffff
inline int read() {
    int x = 0,f = 1;
    char ch = getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f = -1; ch = getchar(); }
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x * f;
}
struct point{
    int fr,to,val;
    int nxt;
}edge[N];
int cur[N];//听说可以弧优化
int head[N];
int cnt;
void add_edge(int x,int y,int z)
{
    edge[cnt].fr=x,edge[cnt].to=y,edge[cnt].val=z;
    edge[cnt].nxt=head[x],head[x]=cnt++;
    edge[cnt].fr=y,edge[cnt].to=x,edge[cnt].val=0;
    edge[cnt].nxt=head[y],head[y]=cnt++;
}
//我放弃链式前向星
int n,m,st,ed;
int deep[N];
int BFS()
{
    queue<int>q;
    for(int i=0;i<=n;i++) cur[i]=head[i],deep[i]=0;
    q.push(st);
    deep[st]=1;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u];i!=-1;i=edge[i].nxt)
        {
            int tmp=edge[i].to;
            if(edge[i].val<=0 || deep[tmp]) continue;
            deep[tmp]=deep[u]+1;
            q.push(tmp);
        }
    }
    return deep[ed];
}
int ans;
int dfs(int u,int flow)//flow为到达终点最多能增广的值
{
    if(u==ed) return flow;
    int add=0;
    for(int i=cur[u];i!=-1&&add<flow;i=edge[i].nxt)
    {
        cur[u]=i;
        int v=edge[i].to;
        if(deep[v]!=deep[u]+1) continue;
        if(!edge[i].val) continue;//剪枝
        int tmpadd=dfs(v,min(edge[i].val,flow-add));
        edge[i].val-=tmpadd;
        edge[i^1].val+=tmpadd;//sub
        add+=tmpadd;
    }
    return add;
}
void Dinic()
{
    while(BFS()) ans+=dfs(st,INF);
}
int main()
{
    n=read(),m=read(),st=read(),ed=read();
    memset(head,-1,sizeof(head));
    for(int i=1,u,v,co;i<=m;i++)
    {
        u=read(),v=read(),co=read();
        add_edge(u,v,co);
    }
    Dinic();
    printf("%d\n",ans);
    return 0;
}

by info___tion @ 2018-12-23 00:16:37

当前弧优化啊


by 哔哩哔哩 @ 2018-12-23 00:18:27

@info___tion 不是很懂,求请教(不知道我的cur是不是写错了)


by Sai0511 @ 2018-12-23 00:22:01

@哔哩哔哩 表示ek过了。。应该是你写错了吧


by info___tion @ 2018-12-23 00:22:22

@哔哩哔哩 你这代码的问题似乎有些大……


by info___tion @ 2018-12-23 00:23:08

首先,Dinic的层次图貌似不能清零(不然好像会错),所以我看到你那个deep数组清零的时候……


by info___tion @ 2018-12-23 00:29:46

当前弧优化就是在DFS里面枚举增广路上的边时,把你那个cur数组拉进循环里面再加个引用。

应该是这样:

for(int& i=cur[u];

然后每次BFS完都要把cur清零(如果是链式前向星就令cur[i]=Head[i](就是链表的头指针)

在你的代码里面应该是这样:

while(BFS())
{
    for(int i=1;i<=n;i++)
        cur[i]=head[i];

    ans+=dfs(st,INF);
}

|