Advertisement
Mlxa

ALGO KUN ( O(M sqrt(N)) )

Jan 20th, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.07 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cassert>
  3. #include <iostream>
  4. #include <set>
  5. #include <vector>
  6. #include <algorithm>
  7.  
  8. namespace Mlxa
  9. {
  10.     using namespace std;
  11.     typedef   long long         ll;
  12.  
  13.     #define read                cin
  14.     #define eol                 '\n'
  15.     #define endln               cout << eol
  16.  
  17.     template <class A>              inline void print   (A a)           { cout << a << ' '; }
  18.     template <class A>              inline void println (A a)           { cout << a << eol; }
  19.     template <class A, class... B>  inline void println (A a, B... b)   { print(a); println(b...); }
  20.     template <class It> ostream&
  21.     operator << (ostream& out, pair<It, It> &c) {
  22.         out << "{ "; -- c.second;
  23.         for (It i(c.first); i != c.second; ++ i)
  24.             out << *i << ", ";
  25.         out << *c.second << " }"; return out;
  26.     }
  27.  
  28.     template <class A>              inline void err     (A a)         { cerr << a << ' '; }
  29.     template <class A>              inline void errln   (A a)         { cerr << a << eol; }
  30.     template <class A, class... B>  inline void errln   (A a, B... b) { err(a); errln(b...); }
  31.  
  32.  
  33.     #ifdef AC
  34.         #define add_log(...) errln("log | ", __VA_ARGS__)
  35.     #else
  36.         #define add_log(...) (void(0))
  37.     #endif
  38.  
  39.     template <class A> inline ll get_size(A a) { return a.size(); }
  40.     #define pb                  push_back
  41.     #define mp                  make_pair
  42.     #define all(x)              begin(x), end(x)
  43.  
  44.     #define openFiles(name)     freopen(name ".in", "r", stdin), freopen(name ".out", "w", stdout)
  45.     #define fastIO              ios_base::sync_with_stdio(false), cin.tie(nullptr)
  46. } using namespace Mlxa;
  47.  
  48. const ll max_n (2005);
  49.  
  50. string M[max_n];
  51. ll dfs_cnt(0);
  52. inline ll get_num (ll i, ll j)
  53. {   i += 3, j += 3; return i * 100 + j; }
  54. inline void get_pos (ll &a, ll &b, ll num)
  55. {   a = num / 100; b = num % 100; a -= 3; b -= 3;   }
  56.  
  57. void paint2 (ll i, ll j, ll a, ll b)
  58. {
  59.     static char cnt = 'A';
  60.     M[i][j] = M[a][b] = cnt;
  61.     if (cnt == 'Z') cnt = 'a';
  62.     else            ++ cnt;
  63.     assert(cnt - 1 <= 'z');
  64. }
  65.  
  66. namespace matching
  67. {
  68.     ll color(1), edg_size(0);
  69.     set<ll> part[2];
  70.     ll used[max_n], match[max_n];
  71.     vector<ll> edges[max_n];
  72.  
  73.     void greed ()
  74.     {
  75.         for (ll i : part[0])
  76.             for (ll j : edges[i])
  77.             if (match[j] < 0) {
  78.                 match[i] = j;
  79.                 match[j] = i;
  80.                 break;
  81.             }
  82.     }
  83.  
  84.     bool dfs (ll v)
  85.     {   add_log("dfs", v); ++ dfs_cnt;
  86.         if (used[v] == color) return false;
  87.         used[v] = color;
  88.         for (ll u : edges[v])
  89.         if (match[u] < 0 || dfs(match[u])) {
  90.             match[v] = u;
  91.             match[u] = v;
  92.             return true;
  93.         }
  94.         return false;
  95.     }
  96.  
  97.     void find (ll n)
  98.     {
  99.         fill(all(used), 0);
  100.         fill(all(match), -1);
  101.         greed();
  102.  
  103.         color = true;
  104.         for (ll run(true); run; ++ color) {
  105.             run = false;
  106.             for (ll i : part[0])
  107.             if (match[i] < 0 && dfs(i))
  108.                 run = true;
  109.         }
  110.     }
  111.  
  112.     bool save_results (ll n, ll m)
  113.     {
  114.         if ( ll(part[0].size() + part[1].size()) < n * m ) return false;
  115.         for (ll i : part[0]) {
  116.             if (match[i] < 0) return false;
  117.             ll j = match[i];
  118.             ll a, b, c, d;
  119.             get_pos(a, b, i);
  120.             get_pos(c, d, j);
  121.             paint2(a,b, c,d);
  122.         } return true;
  123.     }
  124. }
  125.  
  126. ll n, m;
  127.  
  128. void add_edge (ll i, ll j, ll a, ll b)
  129. {   using namespace matching;
  130.     ll pij = (i % 2 == j % 2), pab = (a % 2 == b % 2);
  131.     assert(pij != pab);
  132.     ++ edg_size;
  133.     i = get_num(i, j);
  134.     j = get_num(a, b);
  135.     part[pij].insert(i);
  136.     part[pab].insert(j);
  137.     edges[i].push_back(j);
  138.     edges[j].push_back(i);
  139. }
  140.  
  141. void start ()
  142. {
  143.     fastIO;
  144.     read >> n >> m;
  145.     add_log("|V| =", n, "|E| =", m);
  146.     for (ll i(0); i < n; ++ i)
  147.         read >> M[i];
  148.     for (ll i(0); i < n; ++ i)
  149.         for (ll j(0); j < m; ++ j)
  150.         {
  151.             if (i && M[i][j] != M[i - 1][j]) add_edge(i, j, i - 1, j);
  152.             if (j && M[i][j] != M[i][j - 1]) add_edge(i, j, i, j - 1);
  153.         }
  154. }
  155.  
  156. int main ()
  157. {
  158.     start();
  159.     matching::find(n);
  160.     if ( matching::save_results(n, m) ) {
  161.         println("Yes");
  162.         for (ll i(0); i < n; ++ i)
  163.             println(M[i]);
  164.     } else println("No");
  165.     return 0;
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement