• P2172 [国家集训队]部落战争【最小路径覆盖】


    题目背景

    lanzerb 的部落在 A 国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土。

    题目描述

    A 国是一个 M imes NM×N 的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住。lanzerb 把自己的部落分成若干支军队,他们约定:

    每支军队可以从任意一个城镇出发,并只能从上往向下征战,不能回头。途中只能经过城镇,不能经过高山深涧。

    如果某个城镇被某支军队到过,则其他军队不能再去那个城镇了。 每支军队都可以在任意一个城镇停止征战。

    所有军队都很奇怪,他们走的方法有点像国际象棋中的马。不过马每次只能走 1 imes21×2 的路线,而他们只能走 R imes CR×C 的路线。

    lanzerb 的野心使得他的目标是统一全国,但是兵力的限制使得他们在配备人手时力不从心。假设他们每支军队都能顺利占领这支军队经过的所有城镇,请你帮 lanzerb 算算至少要多少支军队才能完成统一全国的大业。

    输入格式

    第一行包含 44 个整数 M,N,R,CM,N,R,C,意义见问题描述。接下来 MM 行每行一个长度为 NN 的字符串。如果某个字符是 . 表示这个地方是城镇;如果这个字符时 x 则表示这个地方是高山深涧。

    输出格式

    输出一个整数,表示最少的军队个数。

    输入输出样例

    输入 #1
    3 3 1 2
    ...
    .x.
    ...
    输出 #1
    4
    输入 #2
    5 4 1 1
    ....
    ..x.
    ...x
    ....
    x...
    输出 #2
    5

    思路

      说是国集但貌似很好想是一个最小路径覆盖问题。

      可能本意是考搜索吗?

      针对补充下上一篇题解忘记说的一个问题(写的时候太困了

      最小路径覆盖问题的建图是和普通网络流建图有区别的

      为了保证路径数最小,就必须尽量将两条路线首尾相连

      所以每个点的入点是要连能够接触到的点的出点的。

      针对此题来说,能触碰到的点无非是走马的四种情形。

      x点对建图的影响仅是不能将x点作为起点罢了

      ∵ 最小路径覆盖 = 点数 - 最大独立集

      ∴只要求出最大独立集的大小即可

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 const int inf = 0x3f3f3f3f;
     10 
     11 template<class T>inline void read(T &res)
     12 {
     13     char c;T flag=1;
     14     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     15     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     16 }
     17 
     18 namespace _buff {
     19     const size_t BUFF = 1 << 19;
     20     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     21     char getc() {
     22         if (ib == ie) {
     23             ib = ibuf;
     24             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     25         }
     26         return ib == ie ? -1 : *ib++;
     27     }
     28 }
     29 
     30 int qread() {
     31     using namespace _buff;
     32     int ret = 0;
     33     bool pos = true;
     34     char c = getc();
     35     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     36         assert(~c);
     37     }
     38     if (c == '-') {
     39         pos = false;
     40         c = getc();
     41     }
     42     for (; c >= '0' && c <= '9'; c = getc()) {
     43         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     44     }
     45     return pos ? ret : -ret;
     46 }
     47 
     48 const int maxn = 2e4 + 7;
     49 
     50 int s, t, cnt;
     51 char a[100][100];
     52 int head[maxn << 1], edge[maxn << 1], nxt[maxn << 1], vis[maxn << 1];
     53 int w[maxn << 1];//残量网络
     54 int rev[maxn << 1];
     55 int depth[maxn << 1];//图层
     56 int n, m;
     57 
     58 inline int id(int a, int b) {
     59     return (a - 1) * n + b;
     60 }
     61 
     62 inline void BuildGraph(int u, int v, int cap) {
     63     ++cnt;
     64     edge[cnt] = v;
     65     nxt[cnt] = head[u];
     66     rev[cnt] = cnt + 1;
     67     w[cnt] = cap;
     68     head[u] = cnt;
     69 
     70     ++cnt;
     71     edge[cnt] = u;
     72     nxt[cnt] = head[v];
     73     w[cnt] = 0;
     74     rev[cnt] = cnt - 1;
     75     head[v] = cnt;
     76 }
     77 
     78 bool bfs(int x) {
     79     queue<int> q;
     80     while(!q.empty()) {
     81         q.pop();
     82     }
     83     memset(depth, 63, sizeof(depth));
     84     depth[s] = 0;
     85     q.push(s);
     86     do {
     87         int u = q.front();
     88         q.pop();
     89         for ( int i = head[u]; i; i = nxt[i] ) {
     90             int v = edge[i];
     91             if(w[i] > 0 && depth[u] + 1 < depth[v]) {
     92                 depth[v] = depth[u] + 1;
     93                 q.push(v);
     94                 if(v == t) {
     95                     return true;
     96                 }
     97             }
     98         }
     99     } while (!q.empty());
    100     return false;
    101 }
    102 
    103 int dfs(int u, int dist) {
    104     if(u == t) {
    105         return dist;
    106     }
    107     for ( int i = head[u]; i; i = nxt[i] ) {
    108         int v = edge[i];
    109         if(depth[v] == depth[u] + 1 && w[i] > 0) {
    110             int di = dfs(v, min(dist, w[i]));
    111             if(di > 0) {
    112                 w[i] -= di;
    113                 w[rev[i]] += di;
    114                 //vis[u] = v;
    115                 //printf("vis[%d]:%d
    ",u, v);
    116                 return di;
    117             }
    118         }
    119     }
    120     return 0;
    121 }
    122 
    123 bool check(int x, int y) {
    124     if(x >= 1 && x <= m && y >= 1 && y <= n) {
    125         return true;
    126     }
    127     return false;
    128 }
    129 
    130 int main()
    131 {
    132     //freopen("data.txt", "r", stdin);
    133     int r, c;
    134     memset(vis, 0, sizeof(vis));
    135     read(m); read(n); read(r); read(c);
    136     s = 0, t = 2 * n * m + 1;
    137     for ( int i = 1; i <= m; ++i ) {
    138         for ( int j = 1; j <= n; ++j ) {
    139             cin >> a[i][j];
    140         }
    141     }
    142     int cnt = 0;
    143     for ( int i = 1; i <= m; ++i ) {
    144         for ( int j = 1; j <= n; ++j ) {
    145             if(a[i][j] == '.') {
    146                 BuildGraph(s, id(i, j), 1);
    147                 BuildGraph(id(i, j) + n * m, t, 1);
    148                 int nxt_x = i + r, nxt_y = j + c;
    149                 if(check(nxt_x, nxt_y)) {
    150                     BuildGraph(id(i, j), id(nxt_x, nxt_y) + n * m, 1);
    151                 }
    152                 nxt_x = i + r, nxt_y = j - c;
    153                 if(check(nxt_x, nxt_y)) {
    154                     BuildGraph(id(i, j), id(nxt_x, nxt_y) + n * m, 1);
    155                 }
    156                 nxt_x = i + c, nxt_y = j + r;
    157                 if(check(nxt_x, nxt_y)) {
    158                     BuildGraph(id(i, j), id(nxt_x, nxt_y) + n * m, 1);
    159                 }
    160                 nxt_x = i + c, nxt_y = j - r;
    161                 if(check(nxt_x, nxt_y)) {
    162                     BuildGraph(id(i, j), id(nxt_x, nxt_y) + n * m, 1);
    163                 }
    164                 ++cnt;
    165             }
    166         }
    167     }
    168     int ans = 0;
    169     while(bfs(s)) {
    170         //cout << "!" << endl;
    171         int res = dfs(0, 0x7f7f7f7f);
    172         ans += res;
    173     }
    174     //dbg(ans);
    175     // for ( int i = 1; i <= n; ++i ) {
    176     //     if(vis[i]) {
    177     //         int temp = i;
    178     //         do {
    179     //             if(temp > n) {
    180     //                 temp -= n;
    181     //             }
    182     //             printf("%d ",temp);
    183     //             int x = vis[temp];
    184     //             vis[temp] = 0;
    185     //             temp = x;
    186     //         } while (temp != 0);
    187     //         puts("");
    188     //     }
    189     // }
    190     printf("%d
    ",cnt - ans);
    191     return 0;
    192 }
    View Code
    #include <bits/stdc++.h>
    #define dbg(x) cout << #x << "=" << x << endl
    #define eps 1e-8
    #define pi acos(-1.0)

    using namespace std;
    typedef long long LL;

    const int inf = 0x3f3f3f3f;

    template<class T>inline void read(&res)
    {
        char c;T flag=1;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
        while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }

    namespace _buff {
        const size_t BUFF = 1 << 19;
        char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
        char getc() {
            if (ib == ie) {
                ib = ibuf;
                ie = ibuf + fread(ibuf, 1, BUFF, stdin);
            }
            return ib == ie ? -1 : *ib++;
        }
    }

    int qread() {
        using namespace _buff;
        int ret = 0;
        bool pos = true;
        char c = getc();
        for (; (< '0' || c > '9') && c != '-'; c = getc()) {
            assert(~c);
        }
        if (== '-') {
            pos = false;
            c = getc();
        }
        for (; c >= '0' && c <= '9'; c = getc()) {
            ret = (ret << 3) + (ret << 1) + (^ 48);
        }
        return pos ? ret : -ret;
    }

    const int maxn = 2e4 + 7;

    int s, t, cnt;
    char a[100][100];
    int head[maxn << 1], edge[maxn << 1], nxt[maxn << 1], vis[maxn << 1];
    int w[maxn << 1];//残量网络
    int rev[maxn << 1];
    int depth[maxn << 1];//图层
    int n, m;

    inline int id(int a, int b) {
        return (- 1) * n + b;
    }

    inline void BuildGraph(int u, int v, int cap) {
        ++cnt;
        edge[cnt] = v;
        nxt[cnt] = head[u];
        rev[cnt] = cnt + 1;
        w[cnt] = cap;
        head[u] = cnt;

        ++cnt;
        edge[cnt] = u;
        nxt[cnt] = head[v];
        w[cnt] = 0;
        rev[cnt] = cnt - 1;
        head[v] = cnt;
    }

    bool bfs(int x) {
        queue<int> q;
        while(!q.empty()) {
            q.pop();
        }
        memset(depth, 63, sizeof(depth));
        depth[s] = 0;
        q.push(s);
        do {
            int u = q.front();
            q.pop();
            for ( int i = head[u]; i; i = nxt[i] ) {
                int v = edge[i];
                if(w[i] > 0 && depth[u] + 1 < depth[v]) {
                    depth[v] = depth[u] + 1;
                    q.push(v);
                    if(== t) {
                        return true;
                    }
                }
            }
        } while (!q.empty());
        return false;
    }

    int dfs(int u, int dist) {
        if(== t) {
            return dist;
        }
        for ( int i = head[u]; i; i = nxt[i] ) {
            int v = edge[i];
            if(depth[v] == depth[u] + 1 && w[i] > 0) {
                int di = dfs(v, min(dist, w[i]));
                if(di > 0) {
                    w[i] -= di;
                    w[rev[i]] += di;
                    //vis[u] = v;
                    //printf("vis[%d]:%d ",u, v);
                    return di;
                }
            }
        }
        return 0;
    }

    bool check(int x, int y) {
        if(>= 1 && x <= m && y >= 1 && y <= n) {
            return true;
        }
        return false;
    }

    int main()
    {
        //freopen("data.txt", "r", stdin);
        int r, c;
        memset(vis, 0, sizeof(vis));
        read(m); read(n); read(r); read(c);
        s = 0, t = 2 * n * m + 1;
        for ( int i = 1; i <= m; ++) {
            for ( int j = 1; j <= n; ++) {
                cin >> a[i][j];
            }
        }
        int cnt = 0;
        for ( int i = 1; i <= m; ++) {
            for ( int j = 1; j <= n; ++) {
                if(a[i][j] == '.') {
                    BuildGraph(s, id(i, j), 1);
                    BuildGraph(id(i, j) + n * m, t, 1);
                    int nxt_x = i + r, nxt_y = j + c;
                    if(check(nxt_x, nxt_y)) {
                        BuildGraph(id(i, j), id(nxt_x, nxt_y) + n * m, 1);
                    }
                    nxt_x = i + r, nxt_y = j - c;
                    if(check(nxt_x, nxt_y)) {
                        BuildGraph(id(i, j), id(nxt_x, nxt_y) + n * m, 1);
                    }
                    nxt_x = i + c, nxt_y = j + r;
                    if(check(nxt_x, nxt_y)) {
                        BuildGraph(id(i, j), id(nxt_x, nxt_y) + n * m, 1);
                    }
                    nxt_x = i + c, nxt_y = j - r;
                    if(check(nxt_x, nxt_y)) {
                        BuildGraph(id(i, j), id(nxt_x, nxt_y) + n * m, 1);
                    }
                    ++cnt;
                }
            }
        }
        int ans = 0;
        while(bfs(s)) {
            //cout << "!" << endl;
            int res = dfs(0, 0x7f7f7f7f);
            ans += res;
        }
        //dbg(ans);
        // for ( int i = 1; i <= n; ++i ) {
        //     if(vis[i]) {
        //         int temp = i;
        //         do {
        //             if(temp > n) {
        //                 temp -= n;
        //             }
        //             printf("%d ",temp);
        //             int x = vis[temp];
        //             vis[temp] = 0;
        //             temp = x;
        //         } while (temp != 0);
        //         puts("");
        //     }
        // }
        printf("%d ",cnt - ans);
        return 0;
    }
  • 相关阅读:
    【树状数组】bzoj2743 [HEOI2012]采花
    【二分答案】bzoj1639 [Usaco2007 Mar]Monthly Expense 月度开支
    【二分答案】【最短路】bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线
    【二分答案】【Heap-Dijkstra】bzoj2709 [Violet 1]迷宫花园
    【二分答案】【字符串哈希】bzoj2084 [Poi2010]Antisymmetry
    【二分答案】【最大流】bzoj1305 [CQOI2009]dance跳舞
    【计算几何】【二分答案】【最大流】bzoj1822 [JSOI2010]Frozen Nova 冷冻波
    【二分答案】【最大流】bzoj3130 [Sdoi2013]费用流
    【动态规划】bzoj3992 [Sdoi2015]序列统计 10分
    【二分答案】【最大流】bzoj3993 [Sdoi2015]星际战争
  • 原文地址:https://www.cnblogs.com/orangeko/p/12655326.html
Copyright © 2020-2023  润新知