nasarouf

gcj17qD

Apr 9th, 2017
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.88 KB | None | 0 0
  1. //AC GCJ 2017qualD https://code.google.com/codejam/contest/3264486/dashboard#s=p3
  2. #include <cstdio>
  3. #include <string>
  4. #include <iostream>
  5. #include <sstream>
  6. #include <cmath>
  7. #include <map>
  8. #include <set>
  9. #include <functional>
  10. #include <vector>
  11. using namespace std;
  12.  
  13. //usage: Flow<int> f(n); /*make graph using f.conn...*/ f.reserflow(); f.flow(0,1); f.f[][] wil have the flow values
  14.  
  15. #define MAX 404
  16.  
  17. template<class Node, class adjType, class fromType>
  18. bool bfs(Node a, Node b, const adjType &adj, function<bool(int, int)> rc, fromType &from) {
  19.     static Node q[MAX]; int qh = 0, qt = 0; q[qh++] = a;
  20.     static map<Node, int> visited; static int flag = 0;
  21.     visited[a] = ++flag;
  22.     while (qh > qt) {
  23.         a = q[qt++]; if (a == b) return true;
  24.         for (Node j : adj[a]) {
  25.             if (rc(a, j) && visited[j] != flag) {
  26.                 visited[j] = flag; q[qh++] = j; from[j] = a;
  27.                 if (j == b) return true;
  28.             }
  29.         }
  30.     }
  31.     return false;
  32. }
  33.  
  34. template<class T>
  35. class Flow {
  36. public:
  37.     int n;
  38.     vector<set<int>> adj;
  39.     vector<vector<T>> c, f;
  40.  
  41.     inline void connect(int a,int b,T cap) {adj[a].insert(b);adj[b].insert(a);c[a][b]=(cap);}
  42.     inline void disconnect(int a,int b) {adj[a].erase(b);adj[b].erase(a);c[a][b]=0;}
  43.     inline void conn(int a, int b) { connect(a, b, 1); }
  44.     inline T residual(int i, int j){ return (c[i][j] - f[i][j]); }
  45.  
  46.     Flow(int _n=0):n(_n),adj(n,set<int>()), c(n, vector<T>(n, (T)0)), f(n, vector<T>(n, (T)0)) {}
  47.     void resetflow() { for (int i = 0; i < n; i++) for (auto j : adj[i]) f[i][j] = 0; }
  48.     T flow(int src = 0, int sink = 1) {
  49.         vector<int> from(n,0);
  50.         const auto &cc = c, &ff = f;
  51.         while (bfs(src, sink, adj, [=,&cc,&ff](int i, int j) mutable {return ((cc[i][j] - ff[i][j]) > 0); }, from)){
  52.             for (int b = 1; b != 0; b = from[b]){ f[from[b]][b] += 1; f[b][from[b]] -= 1; }
  53.         }
  54.         T sm = 0; for (int i = 2; i < n; i++) sm += f[0][i];
  55.         return sm;
  56.     }
  57. };
  58.  
  59. char board[MAX][MAX], inboard[MAX][MAX];
  60.  
  61. int main() {
  62.     ios_base::sync_with_stdio(false); cin.tie(NULL);
  63.     int t, n, m;  cin >> t; for (int u = 0; u < t; u++) {
  64.         cin >> n >> m; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) board[i][j] = inboard[i][j] = '.';
  65.         char s[100];
  66.         for (int i = 0; i < m; i++) {
  67.             int r, c; cin >> s >> r >> c; r--; c--;
  68.             board[r][c] = inboard[r][c] = s[0];
  69.         }
  70.         {//x
  71.             int N = n; Flow<int> f(N + N + 2);
  72.             /* MAKE THE GRAPH */
  73.             for (int i = 0; i < N; i++) {
  74.                 f.conn(0, 2 + i);
  75.                 f.conn(2 + N + i, 1);
  76.                 for (int j = 0; j < N; j++) f.conn(2 + i, 2 + N + j);
  77.             }
  78.             for (int i = 0; i < N; i++) {
  79.                 for (int j = 0; j < N; j++) if (board[i][j] == 'x' || board[i][j] == 'o') {
  80.                     f.disconnect(0, 2 + i);
  81.                     f.disconnect(2 + i, 2 + N + j);
  82.                     f.disconnect(2 + N + j, 1);
  83.                 }
  84.             }
  85.             f.flow();
  86.             for (int i = 0; i < N; i++) if (f.f[0][2 + i] > 0) for (int j = 0; j < N; j++)
  87.                 if (f.f[2 + i][2 + N + j] > 0 && f.f[2 + N + j][1] > 0)
  88.                     if (board[i][j] == '+' || board[i][j] == 'o') board[i][j] = 'o'; else  board[i][j] = 'x';
  89.         }
  90.         {//+
  91.             map<pair<int, int>, pair<int, int>> ij2ab;
  92.             for (int i = 0; i < n; i++) {
  93.                 for (int j = 0; j < n; j++) {
  94.                     ij2ab[make_pair(i + j, i - j + n - 1)] = make_pair(i, j);
  95.                 }
  96.             }
  97.             int N = 2 * n - 1; Flow<int> f(N + N + 2);
  98.             /* MAKE THE GRAPH */
  99.             for (int i = 0; i < N; i++) {
  100.                 f.conn(0, 2 + i);
  101.                 f.conn(2 + N + i, 1);
  102.                 for (int j = 0; j < N; j++) {
  103.                     if (ij2ab.find(make_pair(i, j)) == ij2ab.end()) continue;
  104.                     f.conn(2 + i, 2 + N + j);
  105.                 }
  106.             }
  107.             for (int i = 0; i < N; i++) {
  108.                 for (int j = 0; j < N; j++) {
  109.                     if (ij2ab.find(make_pair(i, j)) == ij2ab.end()) continue;
  110.                     int a = ij2ab[make_pair(i, j)].first;
  111.                     int b = ij2ab[make_pair(i, j)].second;
  112.                     //cout << i << "," << (j-(n-1)) << "=" << a << "," << b << endl;
  113.                     if (board[a][b] == '+' || board[a][b] == 'o') {
  114.                         f.disconnect(0, 2 + i);
  115.                         f.disconnect(2 + i, 2 + N + j);
  116.                         f.disconnect(2 + N + j, 1);
  117.                     }
  118.                 }
  119.             }
  120.             f.flow();
  121.             for (int i = 0; i < N; i++) if (f.f[0][2 + i]) for (int j = 0; j < N; j++) if (f.f[2 + i][2 + N + j]) {
  122.                 if (ij2ab.find(make_pair(i, j)) == ij2ab.end()) continue;
  123.                 int a = ij2ab[make_pair(i, j)].first;
  124.                 int b = ij2ab[make_pair(i, j)].second;
  125.                 if (board[a][b] == 'x' || board[a][b] == 'o') board[a][b] = 'o'; else  board[a][b] = '+';
  126.             }
  127.         }
  128.         //for (int i = 0; i < n; i++) {
  129.         //  for (int j = 0; j < n; j++) cout << board[i][j];
  130.         //  cout << endl;
  131.         //}
  132.  
  133.         int tot = 0, cnt=0;
  134.         for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {
  135.             if (board[i][j] == 'o') tot += 2; else if (board[i][j] != '.') tot++;
  136.             if (board[i][j] != inboard[i][j]) cnt++;
  137.         }
  138.         cout << "Case #" << (u + 1) << ": " << tot << " " << cnt << endl;
  139.         for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {
  140.             if (board[i][j] != inboard[i][j]) cout << board[i][j] << " " << (i + 1) << " " << (j + 1) << endl;
  141.         }
  142.         cerr << ".";
  143.     }
  144.     return 0;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment