• [BZOJ1066][SCOI2007]蜥蜴[最大流]


    每个柱子拆成两个点 连一条柱子高度的边限流

    源点->蜥蜴->汇点 或者 源点->蜥蜴->拆成的第一个点->拆成的第二个点->汇点

    细节多

    #include <bits/stdc++.h>
    using namespace std;
     
    const int MAXN = 1207;
    const int MAXM = 2e5+7;
    const int inf = 0x3f3f3f3f-1;
    char mat1[24][25], mat2[24][25];
    int head[MAXN], dep[MAXN], tot = 1, cur[MAXN], maxflow;
    int n, m, a, b, tmp, s, t, d;
    struct Edge {
      int v, w, next;
    } G[MAXM<<1];
     
    inline void add(int u, int v, int w) {
      G[++tot] = (Edge) {v, w, head[u]};head[u] = tot;
      G[++tot] = (Edge) {u, 0, head[v]};head[v] = tot;
    }
     
    bool bfs(int s, int t) {
      memset(dep, 0x3f, sizeof dep);
      memcpy(cur, head, sizeof head);
      queue<int>q;
      while(!q.empty()) q.pop();
      dep[s] = 0;
      q.push(s);
      while(!q.empty()) {
        int u = q.front();
        q.pop();
        for(int i = head[u]; i; i = G[i].next) {
          int v = G[i].v, w = G[i].w;
          if (dep[v] > inf && w) {
            dep[v] = dep[u] + 1;
            if (v == t) return 1;
            q.push(v);
          }
        }
      }
      return dep[t] < inf;
    }
     
    int dfs(int u, int t, int limit) {
      if (u == t || !limit) return limit;
      int flow = 0, f;
      for(int i = cur[u]; i; i = G[i].next) {
        cur[u] = i;
        int v = G[i].v, w = G[i].w;
        if (dep[v] == dep[u] + 1 && (f = dfs(v, t, min(w, limit)))) {
          flow += f;
          limit -= f;
          G[i].w -= f;
          G[i^1].w += f;
          if (!limit) break;
        }
      }
      return flow;
    }
     
     
    inline int get(int x, int y) {
      return (x-1)*b + y;
    }
    void dinic(int s, int t) {
      while(bfs(s, t)) maxflow += dfs(s, t, inf);
    }
     
    inline bool ok(int x, int y, int xx, int yy) {
      return ((x-xx)*(x-xx)+(y-yy)*(y-yy)<=(d*d) && mat1[x][y] > '0' && mat1[xx][yy] > '0');
    }
    int ans;
    int Get[105][105];
    int main(void) {
      scanf("%d%d%d", &a, &b, &d);
      n = a*b*2; s = n+1, t = n+2;
      for(int i = 1; i <= a; ++i) scanf("%s", mat1[i]+1);
      for(int i = 1; i <= a; ++i) scanf("%s", mat2[i]+1);
      for(int i = 1; i <= a; ++i)
        for(int j = 1; j <= b; ++j) {
          if (mat1[i][j] - '0') add(get(i,j), get(i,j) + a*b, mat1[i][j] - '0');
          if (mat2[i][j] == 'L') ++ans, add(s, get(i,j), 1);
        }
      for(int i = 1; i <= a; ++i)
        for(int j = 1; j <= b; ++j) {
          if (min(a - i + 1, i) <= d || min(b - j + 1, j) <= d) add(get(i,j)+a*b, t, inf);
        }
      for(int i = 1; i <= a; ++i)
        for(int j = 1; j <= b; ++j)
          for(int k = 1; k <= a; ++k)
            for(int l = 1; l <= b; ++l) {
              if (ok(i,j,k,l)) add(get(i,j) + a*b, get(k,l), inf);
            }
      dinic(s, t);
      cout << ans-maxflow << endl;
      return 0;
    }
    
    
  • 相关阅读:
    token
    跨域问题???
    简单使用express
    深拷贝 浅拷贝
    node表单提交初知识!
    11.29
    11.28
    11.27
    11.26每日总结
    11.25每日总结
  • 原文地址:https://www.cnblogs.com/storz/p/10191506.html
Copyright © 2020-2023  润新知