zoukankan      html  css  js  c++  java
  • Sicily 1696. Flows in Grid

    训练的题目

    最大流

    题意:题意直白,就是一个网格从(0,0)编号到(N-1,M-1),每个点可以走到和它相连的4个点,没条边都有容量,为你从(0,0)到(N-1,M-1)的最大流

    1.建图细心一点不要出错,注意检查

    2.无向图,本来建的是无向图,无端端注释掉一部分,WA了一次才想起来怎么注释掉了,改回来过了

    3.建图后,直接上最大流模板,这里用EK

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    #define N 10100
    #define M 100100
    #define INF 0x3f3f3f3f
    
    int n,row,col,tot;
    int head[N];
    struct edge
    {
       int u,v,cap,flow,next;
    }e[M];
    
    int a[N];  //用于bfs搜索时记录最小残余容量
    int p[N];  //邻接表记录路径
    queue<int>q;  //用于bfs搜索
    
    void add(int u ,int v , int cap ,int flow)
    {
       e[tot].u = u;
       e[tot].v = v;
       e[tot].cap = cap;
       e[tot].flow = flow;
       e[tot].next = head[u];
       head[u] = tot++;
    }
    
    void EK(int s ,int t)
    {
       int FLOW = 0;
       while(1)
       {
          while(!q.empty()) q.pop();
          memset(a,0,sizeof(a));
          memset(p,-1,sizeof(p));
          a[s] = INF;
          q.push(s);
    
          while(!q.empty()) //bfs
          {
             int u = q.front();
             q.pop();
             for(int k=head[u]; k!=-1; k=e[k].next)
             {
                int v = e[k].v;
                int cap = e[k].cap;
                int flow = e[k].flow;
    
                if(!a[v] && cap > flow) //未搜索过,且可以增流
                {
                   p[v] = k;  //记录哪条边
                   if(a[u] < cap-flow)  a[v] = a[u];
                   else                 a[v] = cap - flow;
                   q.push(v);
                }
             }
          }
    
          if(!a[t]) break;  //找不到增广路
          for(int k=p[t]; k!=-1; k=p[e[k].u]) //沿路径返回增广
          {
             e[k].flow += a[t];
             e[k^1].flow -= a[t];
          }
          FLOW += a[t];
       }
       printf("%d\n",FLOW);
    }
    
    int main()
    {
       int T;
       scanf("%d",&T);
       while(T--)
       {
          scanf("%d%d",&row,&col);
          memset(head,-1,sizeof(head));
          tot = 0;
          n = row * col - 1;
          int cap,u,v;
          //先输入横边
          for(int i=0; i<row; i++)
             for(int j=0; j<col-1; j++)
             {
                scanf("%d",&cap);
                u=i*col+j;    //当前点
                v=i*col+j+1;  //其右边点
    
                add(u,v,cap,0);  //建立正边u--->v
                add(v,u,0,0);    //反边,容量为0
    
                add(v,u,cap,0);  //无向图,正边v--->u
                add(u,v,0,0);    //反边,容量为0
             }
    
          //输入竖边
          for(int i=0; i<row-1; i++)
             for(int j=0; j<col; j++)
             {
                scanf("%d",&cap);
                u=i*col+j;      //当前点
                v=(i+1)*col+j; //其下面的点
    
                add(u,v,cap,0);  //正边u--->v
                add(v,u,0,0);    //反边,容量为0
    
                add(v,u,cap,0);   //正边v--->u
                add(u,v,0,0);     //反边,容量为0
             }
    
          EK(0,n);
       }
       return 0;
    }
  • 相关阅读:
    数论模板
    HZNU_TI1050 训练实录
    2019 ICPC Asia Xuzhou Regional
    ICPC 2019-2020 North-Western Russia Regional Contest
    2019 ICPC Asia Yinchuan Regional
    2019-2020 ICPC, Asia Jakarta Regional Contest
    The 2019 China Collegiate Programming Contest Harbin Site
    2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest
    Educational Codeforces Round 75
    2018-2019 ACM-ICPC, Asia Dhaka Regional Contest
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3052366.html
Copyright © 2011-2022 走看看