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
  • 相关阅读:
    Educational Codeforces Round 85 D. Minimum Euler Cycle(模拟/数学/图)
    Educational Codeforces Round 85 C. Circle of Monsters(贪心)
    NOIP 2017 提高组 DAY1 T1小凯的疑惑(二元一次不定方程)
    Educational Codeforces Round 85 B. Middle Class(排序/贪心/水题)
    Educational Codeforces Round 85 A. Level Statistics(水题)
    IOS中的三大事件
    用Quartz 2D画小黄人
    strong、weak、copy、assign 在命名属性时候怎么用
    用代码生成UINavigationController 与UITabBarController相结合的简单QQ框架(部分)
    Attempting to badge the application icon but haven't received permission from the user to badge the application错误解决办法
  • 原文地址:https://www.cnblogs.com/cychester/p/9502589.html
Copyright © 2011-2022 走看看