• Gym


     Gym - 100203I  I WIN

    题意:一个n*m的矩阵包含W,I,N三种字符,问相邻的字符最多能组成不重叠的WIN。

    思路:比赛的时候没有发现是网络流,,居然一度以为是二分图匹配,,写了一下没过就没改了,,知道了是网络流就好办了。设一个起点一个终点,起点和每个W之间连一条边,N和终点间连一条边,W和I之间连一条边,I和N之间连一条边,不过这里为了避免重复使用同一个I,应改成W到I连一条边,I连一条边到I',再从I'连一条边到N就可以保证最优解了。求一遍最大流即可。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <fstream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <deque>
      7 #include <vector>
      8 #include <queue>
      9 #include <string>
     10 #include <cstring>
     11 #include <map>
     12 #include <stack>
     13 #include <set>
     14 #define LL long long
     15 #define eps 1e-8
     16 #define INF 0x3f3f3f3f
     17 #define MAXN 1005
     18 using namespace std;
     19 
     20 struct Edge{
     21     int from, to, cap, flow;
     22     //Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){};
     23 };
     24 struct Dinic{
     25     int n, m, i, s, t;
     26     Edge e;
     27     vector<Edge> edges;
     28     vector<int> G[MAXN];
     29     int d[MAXN], cur[MAXN];
     30     bool vis[MAXN];
     31     void init(int n){
     32         this->n = n;
     33         for (i = 0; i <= n; i++){
     34             G[i].clear();
     35         }
     36         edges.clear();
     37     }
     38     void AddEdge(int from, int to, int cap){
     39         edges.push_back(Edge{ from, to, cap, 0 });
     40         edges.push_back(Edge{ to, from, 0, 0 });
     41         m = edges.size();
     42         G[from].push_back(m - 2);
     43         G[to].push_back(m - 1);
     44     }
     45     bool BFS(){
     46         memset(vis, 0, sizeof(vis));
     47         queue<int> Q;
     48         Q.push(s);
     49         d[s] = 0;
     50         vis[s] = 1;
     51         while (!Q.empty()){
     52             int x = Q.front();
     53             Q.pop();
     54             for (i = 0; i < G[x].size(); i++){
     55                 Edge& e = edges[G[x][i]];
     56                 if (!vis[e.to] && e.cap > e.flow){
     57                     vis[e.to] = true;
     58                     d[e.to] = d[x] + 1;
     59                     Q.push(e.to);
     60                 }
     61             }
     62         }
     63         return vis[t];
     64     }
     65     int DFS(int x, int a){
     66         if (x == t || a == 0) return a;
     67         int flow = 0, f;
     68         for (int& i = cur[x]; i < G[x].size(); i++){
     69             Edge& e = edges[G[x][i]];
     70             if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0){
     71                 e.flow += f;
     72                 edges[G[x][i] ^ 1].flow -= f;
     73                 flow += f;
     74                 a -= f;
     75                 if (a == 0) break;
     76             }
     77         }
     78         return flow;
     79     }
     80     int MaxFlow(int s, int t, int need){
     81         int flow = 0;
     82         this->s = s;
     83         this->t = t;
     84         while (BFS()){
     85             memset(cur, 0, sizeof(cur));
     86             flow += DFS(s, INF);
     87             if (flow > need) return flow;
     88         }
     89         return flow;
     90     }
     91 };
     92 char a[50][50];
     93 Dinic p;
     94 const int step[4][2] = { 1, 0, 0, 1, -1, 0, 0, -1 };
     95 bool vis[25][25];
     96 int main()
     97 {
     98 #ifndef ONLINE_JUDGE
     99     freopen("in.txt", "r", stdin);
    100     //freopen("out.txt", "w", stdout);
    101 #endif // OPEN_FILE
    102     int n, m;
    103     scanf("%d%d", &n, &m);
    104     for (int i = 1; i <= n; i++){
    105         scanf("%s", a[i] + 1);
    106     }
    107     int s = 0, t = 2 * n * m + 1;
    108     p.init(t);
    109     memset(vis, 0, sizeof(vis));
    110     for (int i = 1; i <= n; i++){
    111         for (int j = 1; j <= m; j++){
    112             int u = (i - 1) * m + j;
    113             if(a[i][j] == 'W'){
    114                 p.AddEdge(s, u, 1);
    115                 for (int k = 0; k < 4; k++){
    116                     int x = i + step[k][0];
    117                     int y = j + step[k][1];
    118                     if (x < 1 || y < 1 || x > n || y > m) continue;
    119                     if (a[x][y] == 'I'){
    120                         p.AddEdge(u, (x - 1) * m + y, 1);
    121                     }
    122                 }
    123             }
    124             else if (a[i][j] == 'I'){
    125                 int v = u + n * m;
    126                 p.AddEdge(u, v, 1);
    127                 for (int k = 0; k < 4; k++){
    128                     int x = i + step[k][0];
    129                     int y = j + step[k][1];
    130                     if (x < 1 || y < 1 || x > n || y > m) continue;
    131                     if (a[x][y] == 'N'){
    132                         p.AddEdge(v, (x - 1) * m + y, 1);
    133                         if (vis[x][y]) continue;
    134                         p.AddEdge((x - 1) * m + y, t, 1);
    135                         vis[x][y] = true;
    136                     }
    137                 }
    138             }
    139         }
    140     }
    141     int ans = p.MaxFlow(s, t, INF);
    142     printf("%d
    ", ans);
    143 }
  • 相关阅读:
    VS2017使用inet_ntoa()产生错误的解决方法
    ET框架:如何运行ET-Demo
    ProtoBuf入门
    AssetBundle入门
    UML图写法
    Visual Studio小技巧-引用项目外部的类
    UnityECS(一)UnityECS学习资料
    关于如何利用MySQL Workbench导入Excel表格
    SublimeText3插件安装(未完更新)
    Unity中Animator的2DSprite动画控制与使用
  • 原文地址:https://www.cnblogs.com/macinchang/p/4733443.html
Copyright © 2020-2023  润新知