zoukankan      html  css  js  c++  java
  • BZOJ 3171[TJOI2013] 循环格

    题解

    刚开始我也没看出来是个网络流QAQ,觉得还是有点难想:(

    要满足每一个点都在一个循环内, 必须满足每个点出度和入度为1。

    所以将每个点拆成两个点, 一个点为与S相连, 另一个点与T相连, 容量为1,费用为0。

    然后每个点向它指向的点连容量为1, 费用为0的边, 向周围的其他点连容量为1, 费用为1的点

    这样建图保证了最大流为点数, 也即每个点入度都为1。

    跑费用流就可以算出答案。

    代码

      1 #include<cstring>
      2 #include<queue>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #define rd read()
      6 #define rep(i,a,b) for( int i = (a); i <= (b); ++i)
      7 #define per(i,a,b) for( int i = (a); i >= (b); --i)
      8 using namespace std;
      9 
     10 const int N = 1e4;
     11 const int inf = 1061109567;
     12 
     13 int head[N], S, T = N - 1, dis[N], n, m, tot, pre[N], minco, maxflow, vis[N];
     14 int dx[4] = {0, 0, -1, 1}, dy[4] = {1, -1, 0, 0};
     15 
     16 char s[20];
     17 
     18 queue<int> q;
     19 
     20 struct edge {
     21     int nxt, val, to, c;
     22 }e[N << 1];
     23 
     24 int read() {
     25     int X = 0, p = 1;char c = getchar();
     26     for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1;
     27     for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
     28     return X * p;
     29 }
     30 
     31 int ch(int x) {
     32     return ((x + 1) ^ 1) - 1;
     33 }
     34 
     35 int tn(int x, int y) {
     36     return x * m + y + 1;
     37 }
     38 
     39 void added(int fr, int to, int val, int c) {
     40     e[++tot].to = to;
     41     e[tot].val = val;
     42     e[tot].c = c;
     43     e[tot].nxt = head[fr];
     44     head[fr] = tot;
     45 }
     46 
     47 void add(int fr, int to, int val, int c) {
     48     added(fr, to, val, c);
     49     added(to, fr, 0, -c);
     50 }
     51 
     52 int bfs() {
     53     memset(dis, 63, sizeof(dis));
     54     memset(pre, 0, sizeof(pre));
     55     memset(vis, 0, sizeof(vis));
     56     q.push(S);
     57     dis[S] = 0;
     58     for(int u, nt; !q.empty(); ) {
     59         u = q.front(); q.pop();
     60         for(int i = head[u]; i; i = e[i].nxt) {
     61             nt = e[i].to;
     62             if(dis[nt] <= dis[u] + e[i].c || !e[i].val) continue;
     63             dis[nt] = dis[u] + e[i].c;
     64             pre[nt] = i;
     65             if(!vis[nt]) vis[nt] = 1, q.push(nt);
     66         }
     67         vis[u] = 0;
     68     }
     69     return dis[T];
     70 }
     71 
     72 void EK() {
     73     for(; bfs() != inf; ) {
     74         int tmp = inf;
     75         for(int i = pre[T]; i; i = pre[e[ch(i)].to]) tmp = min(tmp, e[i].val);
     76         for(int i = pre[T]; i; i = pre[e[ch(i)].to]) e[i].val -= tmp, e[ch(i)].val += tmp;
     77         maxflow += tmp;
     78         minco += tmp * dis[T];
     79     }
     80 }
     81 
     82 int main()
     83 {
     84     n = rd; m = rd;
     85     rep(i, 0, n - 1) {
     86         scanf("%s", s);
     87         rep(j, 0, m - 1) {
     88             rep(k, 0, 3) {
     89                 int nx = (i + dx[k]) % n, ny = (j + dy[k]) % m;
     90                 nx = (nx + n) % n; ny = (ny + m) % m;
     91                 add(tn(i, j), tn(nx, ny) + n * m, 1, 1);
     92             }
     93             int flag;
     94             if(s[j] == 'U') flag = 2;
     95             if(s[j] == 'D') flag = 3;
     96             if(s[j] == 'L') flag = 1;
     97             if(s[j] == 'R') flag = 0;
     98             int nx = (i + dx[flag]) % n, ny = (j + dy[flag]) % m;
     99             nx = (nx + n) % n; ny = (ny + m) % m;
    100             add(tn(i, j), tn(nx, ny) + n * m, 1, 0);
    101         }
    102     }
    103     rep(i, 0, n - 1) rep(j, 0, m - 1) {
    104         add(S, tn(i, j), 1, 0);
    105         add(tn(i, j) + n * m, T, 1, 0);
    106     }
    107     EK();
    108     printf("%d
    ", minco);
    109 }
    View Code
  • 相关阅读:
    android工程下assets与raw文件夹
    eclipse增加jar包方式对比
    跳出内循环,继续下一次外循环的写法
    ImportError: cannot import name 'BaseDataset' from 'src.dataset'
    神经网络中的反向传播法
    Pytorch中ndarray tensor list互转
    Python运行语法错误:IndentationError: unindent does not match any outer indentation level
    module 'torch' has no attribute 'gesv'
    极大似然估计
    Gaussian Processes
  • 原文地址:https://www.cnblogs.com/cychester/p/9502589.html
Copyright © 2011-2022 走看看