zoukankan      html  css  js  c++  java
  • 洛谷 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。

    思路:建反边,跑dinic算法,dinic算法相比EK算法的好处是有了分层图体系,但是EK算法可以被某些图轻易卡掉,比如一个图源点和汇点之间两边的容量很大,中间很小,那么就可以被卡掉,要注意反边的容量为0。反边的作用是给算法一个反悔的机会。

    代码:

    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #define maxn 10007
    using namespace std;
    const int inf=0x3f3f3f3f;
    int n,m,S,T,d[maxn],head[maxn],num=1;
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct node {
      int u,v,w,nxt;
    }e[maxn*20];
    inline void ct(int u, int v, int w) {
      e[++num]=node{u,v,w,head[u]};
      head[u]=num;
    }
    inline 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].nxt) {
          int v=e[i].v;
          if(d[v]==-1&&e[i].w) {
            d[v]=d[u]+1;
            q.push(v);
          }
        }
      }
      return d[T]!=-1;
    }
    int dfs(int u, int f) {
      if(u==T) return f;
      int rest=0;
      for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(d[v]==d[u]+1&&e[i].w) {
          int t=dfs(v,min(e[i].w,f-rest));
          if(!t) d[v]=0;
          e[i].w-=t;
          e[i^1].w+=t;
          rest+=t;
          if(f==rest) return f;
        }
      }
      return rest;
    }
    int dinic() {
      int ans=0;
      while(bfs()) ans+=dfs(S,inf);
      return ans;
    }
    int main() {
      n=qread(),m=qread(),S=qread(),T=qread();
      for(int i=1;i<=m;++i) {
        int u=qread(),v=qread(),w=qread();
        ct(u,v,w),ct(v,u,0);
      }
      printf("%d
    ",dinic());
      return 0;
    }
    
  • 相关阅读:
    与众不同 windows phone (50)
    与众不同 windows phone (49)
    重新想象 Windows 8.1 Store Apps (93)
    重新想象 Windows 8.1 Store Apps 系列文章索引
    重新想象 Windows 8.1 Store Apps (92)
    重新想象 Windows 8.1 Store Apps (91)
    重新想象 Windows 8.1 Store Apps (90)
    重新想象 Windows 8.1 Store Apps (89)
    重新想象 Windows 8.1 Store Apps (88)
    重新想象 Windows 8.1 Store Apps (87)
  • 原文地址:https://www.cnblogs.com/grcyh/p/10569787.html
Copyright © 2011-2022 走看看