• Learning:多路增广费用流


    Learning

    多路增广费用流

    好吧,只有我觉得这玩意儿好像就是一个spfa标号的dicnic吗

    参考dicnic,每次把bfs改成spfa,然后依据(d_u leqslant d_c + w(u,v))分层就可以了。。。

    代码

    /*
    xsy2692
    */
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int N = 100 + 10;
    const int maxn = 500 + 10;
    const int INF = 0x3f3f3f3f;
    const int Node = 10010;
    const int E = 200000;
     
    inline int rd()
    {
        int x=0;char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        return x;
    }
     
    int R, C, n, A, B, xx[8], yy[8], Ans = 0, S, T;
    char s[N][N];
     
    int h[Node], ecnt;
    struct enode{
      int v, n, w, c, op;
      enode() {}
      enode(int _v, int _n, int _w, int _c, int _op):v(_v), n(_n), w(_w), c(_c), op(_op) {}
    }e[E << 1];
     
    inline void addedge(int u, int v, int w, int c) {
    //  cout << u << ' ' << v << ' ' << ((c >= INF) ? (-1) : (c)) << endl;
        ecnt ++; e[ecnt] = enode(v,h[u],w,c,ecnt + 1); h[u] = ecnt;
        ecnt ++; e[ecnt] = enode(u,h[v],0,- c,ecnt - 1); h[v] = ecnt;
    }
     
    int dist[Node], p[Node], flow = 0;
    bool inq[Node];
    int q[E];
    inline int spfa() {
        int head, tail;
        head = tail = 1;
      memset(dist,0x3f,sizeof(dist));
      memset(inq,false,sizeof(inq));
      q[tail] = S; inq[S] = true;
      dist[S] = 0; p[S] = -1;
      while(head <= tail) {
        int u = q[head]; head ++;
        for(int i = h[u];~ i;i = e[i].n) {
          int v = e[i].v;
          if(e[i].w > 0 && dist[v] > dist[u] + e[i].c) {
            p[v] = e[i].op;
            dist[v] = dist[u] + e[i].c;
            if(!inq[v]) {
              inq[v] = true;
              q[++ tail] = v;
                    }
                }
            }
            inq[u] = false;
        }
        if(dist[T] >= INF) return 0;
        return 1;
    }
     
    int cur[maxn];
     
    int dfs(int u, int c) {
      if(u == T || c == 0) return c;
      inq[u] = 1;
      int tmp = 0;
      for(int i = cur[u];~ i;i = e[i].n) {
        cur[u] = i;
        int v = e[i].v;
        if(inq[v]) continue;
        if(dist[v] == dist[u] + e[i].c && e[i].w > 0) {
          int x = dfs(v,min(c,e[i].w));
          if(x) {
            e[i].w -= x; e[e[i].op].w += x;
            tmp += x; c -= x;
                    Ans += x * e[i].c;
            if(!c) break;
                }
            }
        }
        return tmp;
    }
     
    int main() {
    //  scanf("%d%d%d%d%d", &R, &C, &n, &A, &B);
      R = rd(); C = rd(); n = rd(); A = rd(); B = rd();
        memset(h,-1,sizeof(h));
        ecnt = 0;
        xx[0] = A; yy[0] = B;
        xx[1] = A; yy[1] = - B;
        xx[2] = - A; yy[2] = B;
        xx[3] = - A; yy[3] = - B;
        xx[4] = B; yy[4] = A;
        xx[5] = B; yy[5] = - A;
        xx[6] = - B; yy[6] = A;
        xx[7] = - B; yy[7] = - A;
        for(int i = 1;i <= R;i ++) {
          scanf("%s", s[i] + 1);
        }
        S = 0; T = R * C + 1;
        for(int i = 1;i <= n;i ++) {
          int x, y;
    //    scanf("%d%d", &x, &y);
        x = rd(); y = rd();
          addedge(S,(x - 1) * C + y,1,0);
        }
        for(int i = 1;i <= n;i ++) {
          int x, y;
    //    scanf("%d%d", &x, &y);
        x = rd(); y = rd();
          addedge((x - 1) * C + y,T,1,0);
        }
        for(int i = 1;i <= R;i ++) {
          for(int j = 1;j <= C;j ++) {
            if(s[i][j] == '*') continue;
            int id = (i - 1) * C + j;
            for(int k = 0;k < 8;k ++) {
              int dx = i + xx[k];
              int dy = j + yy[k];
              if(dx < 1 || dy < 1 || dx > R || dy > C || s[dx][dy] == '*') continue;
              addedge(id,(dx - 1) * C + dy,INF,1);
                }
            }
        }
        Ans = 0;
        while(spfa()) {
            for(int i = S;i <= T;i ++) cur[i] = h[i];
            memset(inq,0,sizeof(inq));
          int x = dfs(S,INF);
          if(x == 0) break;
          flow += x;
        }
        if(flow != n) Ans = -1;
        printf("%d
    ", Ans);
      return 0;
    }
    

    什么你问我复杂度?O(松)

  • 相关阅读:
    grep取缩写|awk两个文件取交集
    p{space}|p{Hex}|p{Digit}|转译符|1|g{-1}|[^ab]|/([^dD]+)/
    线性回归的简单实现mxnet
    线性回归从0实现——mxnet
    决策树(DT)
    C++基本语法(三)存储类及运算符
    C++基本语法(二)数据类型及变量类型、常量
    C++基本语法(一)
    np.zeros((a,b,c))
    python之range()
  • 原文地址:https://www.cnblogs.com/ezhjw/p/10027722.html
Copyright © 2020-2023  润新知