zoukankan      html  css  js  c++  java
  • 【洛谷 3376】网络最大流

    题目描述

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

    输入格式

    第一行包含四个正整数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。

    题解:一篇板子题_介绍一为为啥反边的编号是^1得来的。

                异或,0变1,1变0,2变3,3变2以此类推。当然也可以判断奇偶性

    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    using namespace std;
    const int oo=0x3f3f3f3f;
    const int N=10005;
    int cnt=1,n,m,s,t,u,v,w;
    struct node{
        int next;
        int w;
        int v;
        int u;
    }e[2000005];
    int head[N],d[N];
    void add(int u,int v,int w){
        cnt++; e[cnt].w=w; e[cnt].v=v;
        e[cnt].u=u; e[cnt].next=head[u];
        head[u]=cnt;
    }
    
    bool bfs(){
        memset(d,-1,sizeof(d));
        queue<int>q;
        q.push(s); d[s]=0;
        while(!q.empty()){
            int u=q.front(); q.pop();
            for(int i=head[u];i;i=e[i].next){
                int v=e[i].v;
                if(d[v]==-1 && e[i].w!=0){
                    d[v]=d[u]+1;
                    q.push(v);
                }
            }
        }
        if(d[t]!=-1) return 1;
        else return 0;
    }
    
    int dfs(int u,int f){
        if(u==t) return f;
        int res=0;
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].v;
            if(d[v]==d[u]+1 && e[i].w!=0){
                int t=dfs(v,min(e[i].w,f-res));
                if(!t) d[v]=0;
                e[i].w-=t;  e[i^1].w+=t;
                res+=t; 
                if(f==res) return res;
            }
        }
        return res;
    }
    
    int main(){
        freopen("3376.in","r",stdin);
        freopen("3376.out","w",stdout);
        scanf("%d %d %d %d",&n,&m,&s,&t);
        for(int i=1;i<=m;i++){
            scanf("%d %d %d",&u,&v,&w);
            add(u,v,w); add(v,u,0);
        }
        int ans=0;
        while(bfs())
            ans+=dfs(s,oo);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    linux 命令——48 watch (转)
    linux 命令——47 iostat (转)
    linux 命令——46 vmstat(转)
    linux 命令——45 free(转)
    linux 命令——44 top (转)
    linux 命令——43 killall(转)
    linux 命令——42 kill (转)
    linux 命令——41 ps(转)
    linux 命令——40 wc (转)
    Java for LeetCode 068 Text Justification
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11295953.html
Copyright © 2011-2022 走看看