zoukankan      html  css  js  c++  java
  • 【最大流ISAP】洛谷P3376模板题

    题目描述

    如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。

    输入输出格式

    输入格式:

    第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

    接下来M行每行包含三个正整数ui、vi、wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi)

    输出格式:

    一行,包含一个正整数,即为该网络的最大流。

    输入输出样例

    输入样例#1: 复制
    4 5 4 3
    4 2 30
    4 3 20
    2 3 20
    2 1 30
    1 3 40
    输出样例#1: 复制
    50

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=10,M<=25

    对于70%的数据:N<=200,M<=1000

    对于100%的数据:N<=10000,M<=100000

    样例说明:

    题目中存在3条路径:

    4-->2-->3,该路线可通过20的流量

    4-->3,可通过20的流量

    4-->2-->1-->3,可通过10的流量(边4-->2之前已经耗费了20的流量)

    故流量总计20+20+10=50。输出50。

    题解

    就是最大流的模板题。。。

    ISAP的板子先贴在这里。。。

    虽然平时都用dinic就是了。。。

    代码

    //by 减维
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<map>
    #include<bitset>
    #include<algorithm>
    #define ll long long
    #define maxn 100005
    #define inf 1<<30
    using namespace std;
    
    struct edge{
        int to,ne,v;
    }e[maxn<<1];
    
    int n,m,s,t,ecnt=1,head[maxn],cur[maxn],gap[maxn],level[maxn];
    
    void add(int x,int y,int v)
    {
        e[++ecnt].to=y;
        e[ecnt].v=v;
        e[ecnt].ne=head[x];
        head[x]=ecnt;
    }
    
    void bfs()
    {
        queue<int>q;
        gap[level[t]=1]++;
        for(int i=1;i<=n;++i)cur[i]=head[i];
        q.push(t);
        while(!q.empty())
        {
            int d=q.front();q.pop();
            for(int i=head[d],dd=e[i].to;i;i=e[i].ne,dd=e[i].to)
                if(!level[dd])
                    level[dd]=level[d]+1,gap[level[dd]]++,q.push(dd);
        }
    }
    
    int isap(int x,int maxflow)
    {
        if(x==t)return maxflow;
        int used=0,ff,dd;
        for(int i=cur[x];i;i=e[i].ne)
            if(e[i].v>0&&level[dd=e[i].to]==level[x]-1)
            {
                ff=isap(dd,min(maxflow-used,e[i].v));
                e[i].v-=ff,e[i^1].v+=ff,used+=ff;
                if(e[i].v>0)cur[x]=i;
                if(maxflow==used)return maxflow;
            }
        --gap[level[x]];
        if(!gap[level[x]])level[s]=n+1;
        ++gap[++level[x]];
        cur[x]=head[x];
        return used;
    }
    
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&s,&t);
        for(int i=1,x,y,v;i<=m;++i)
        {
            scanf("%d%d%d",&x,&y,&v);
            add(x,y,v);
            add(y,x,0);
        }
        bfs();
        int ans=0;
        while(level[s]<n+1)ans+=isap(s,inf);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    5 数组 Swift/Object-C ——《Swift3.0从入门到出家》
    4 字符串 Swift/Objective -C ——《Swift3.0从入门到出家》
    3 循环语句——《Swift3.0从入门到出家》
    2 分支语句——《Swift3.0 从入门到出家》
    windows环境下安装epress框架的问题解决方法
    关于rem的使用和less编译工具考拉
    实例了解js面向对象的封装和继承等特点
    CSS3弹性盒模型新版和老版写法差异
    canvas实例:旋转缩放的方块
    用canvas的arc绘制时钟
  • 原文地址:https://www.cnblogs.com/rir1715/p/8136480.html
Copyright © 2011-2022 走看看