Advertisement
nasarouf

gcj17qD

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