MnZn求助ISAP,码风还行求看看

P3376 【模板】网络最大流

Focus_on @ 2021-12-01 17:59:32

rt,可能写法有点不一样,是在教练给的思路下自己写的没看题解。轻D

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;

queue<int> q;

int n,m,s,t,u,v,d;
int dis[210][210],dep[210],sum[210];
bool gap,vis[210];
long long ans=0;

void bfs(){

    q.push(t);
    vis[t]=1;
    dep[t]=0;
    sum[0]=1;

    while(!q.empty()){

        int x=q.front();
        q.pop();

        for(int i=1;i<=n;i++)
        if(!vis[i]&&dis[i][x]){
            q.push(i);
            vis[i]=1;
            dep[i]=dep[x]+1;
            sum[dep[i]]++;
        }
    }
}

int now[210],cnt;

void ISAP(int x,int mn){

    if(gap) return;

    if(x==t){

        ans+=mn;

        for(int i=1;i<cnt;i++)
            dis[now[i]][now[i+1]]-=mn,dis[now[i+1]][now[i]]+=mn;

        return;
    }

    for(int i=1;i<=n;i++)
    if(dis[x][i]&&dep[x]>dep[i]){
        now[++cnt]=i;
        ISAP(i,min(mn,dis[x][i]));
        if(gap) return;
        now[cnt--]=0;
    }

    --sum[dep[x]];
    if(!sum[dep[x]]){
        gap=1;
        return;
    }

    ++dep[x];
    ++sum[dep[x]];
}

int main(){

    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&d);
        dis[u][v]+=d;
    }

    bfs();
    gap=0;

    while(!gap) now[cnt=1]=s,ISAP(s,1e9);

    printf("%lld\n",ans);
    return 0;
}

by JQ6561 @ 2021-12-01 18:35:01

感觉有两个问题 1.要存反边(初始残量为0,更改时增加对应正边减少的流量,一开始的bfs也是在反图上跑的)你好像没存 2.这题有重边,不能用邻接矩阵存边的信息(几天前本人亲身经历过)


by Focus_on @ 2021-12-02 07:44:40

@JQ6561 谢谢指导,1.反边用邻接矩阵好像可以不用存?我好像在更改的时候增加了反边 2. 我用的是 dis[u][v]+=d 啊(雾~),有重边是容量相加吧?


by JQ6561 @ 2021-12-02 17:58:56

重边应该是单独算的吧,不能加一起(反正我之前这么写莫名其妙的WA了)


by Focus_on @ 2021-12-03 17:18:42

@JQ6561 啊这样吗,谢谢大佬


|