joylintp

solve.cpp

Jan 23rd, 2021 (edited)
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.30 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define eb emplace_back
  3.  
  4. typedef long long ll;
  5. typedef std::vector <int> vector;
  6. const int N = 5000, M = 66666;
  7. const ll mod = 18761890748385299;
  8.  
  9. struct edge {
  10.     int u, v;
  11.     edge (int u0 = 0, int v0 = 0) : u(u0), v(v0) {}
  12. } e[M];
  13.  
  14. int R, C, V, E = 0;
  15. int p[N];
  16. int elim[N];
  17. int to[M], first[N], next[M];
  18. int orient[M];
  19.  
  20. inline void addedge(int u, int v) {
  21.     //  fprintf(stderr, "addedge %d %d\n", u, v);
  22.     e[++E] = edge(u, v), next[E] = first[u], first[u] = E;
  23.     e[++E] = edge(v, u), next[E] = first[v], first[v] = E;
  24. }
  25.  
  26. inline void split(int id, int &r, int &c) {r = --id / C + 1, c = id % C + 1;}
  27. inline int ancestor(int x) {return p[x] == x ? x : (p[x] = ancestor(p[x]));}
  28. inline bool join(int x, int y) {
  29.     if ((x = ancestor(x)) == (y = ancestor(y))) return true;
  30.     return p[x] = y, false;
  31. }
  32.  
  33. int posX[N], posY[N];
  34. namespace Planar {
  35. #define ad(x) (((x - 1) ^ 1) + 1)
  36.     int F = 0;
  37.     int belF[M], remain[M], que[M];
  38.     vector face[M];
  39.  
  40.     inline bool judge(int A, int B, int C, int D) {
  41.         if(posX[B] == posX[A] + 1) return posY[D] < posY[C];
  42.         if(posX[B] == posX[A] - 1) return posY[C] < posY[D];
  43.         if(posY[B] == posY[A] + 1) return C < D;
  44.         if(posY[B] == posY[A] - 1) return D < C;
  45.         /*
  46.            if (B == A + ::C) return (D - 1) % ::C < (C - 1) % ::C;
  47.            if (B == A - ::C) return (C - 1) % ::C < (D - 1) % ::C;
  48.            if (B == A + 1) return C < D;
  49.            if (B == A - 1) return D < C;
  50.            */
  51.         std::cerr << A << ' ' << B << ' ' << C << ' ' << D << '\n';
  52.         std::cerr << posX[A] << ' ' << posX[B] << '\n';
  53.         abort();
  54.     }
  55.  
  56.     void dfs(int i) {
  57.         int j, x = e[i].u, y = e[i].v, z, bestV = 0, bestE = 0;
  58.         //      fprintf(stderr, "search face #%d edge #%d (%d, %d)\n", F, i, x, y);
  59.         belF[i] = F, face[F].eb(i);
  60.         for (j = first[y]; j; j = next[j]) {
  61.             if ((z = e[j].v) == x) continue;
  62.             if (!bestV || judge(x, y, z, bestV)) bestV = z, bestE = j;
  63.         }
  64.         if (!bestE) {
  65.             for (j = first[y]; j; j = next[j]) if (e[j].v == x) break;
  66.             bestV = x, bestE = j;
  67.         }
  68.         if (belF[bestE] != F) dfs(bestE);
  69.     }
  70.  
  71.     int main() {
  72.         int i, f, h, t = 0; bool o;
  73.         for (i = 1; i <= E; ++i)
  74.             if (!belF[i]) ++F, dfs(i), remain[F] = face[F].size();
  75.         for (i = 1; i <= F; ++i)
  76.             for (int e : face[i])
  77.                 if (orient[e] && --remain[i] == 1) que[t++] = i;
  78.         for (h = 0; h < t; ++h) {
  79.             f = que[h], o = true;
  80.             if (!remain[f]) continue;
  81.             for (int e : face[f])
  82.                 if (orient[e]) o ^= orient[e] != e;
  83.                 else i = e;
  84.             orient[ad(i)] = orient[i] = (o ? ad(i) : i);
  85.             if (--remain[ f = belF[ad(i)] ] == 1) que[t++] = f;
  86.         }
  87.         for (i = 1; i <= E; ++i) assert(orient[i]);
  88.         return 0;
  89.     }
  90. }
  91.  
  92. using std::cin;
  93.  
  94. int mp[100][100];
  95. int main() {
  96.     int i, j, v, n;
  97.     cin >> R;
  98.     C = R;
  99.     V = 0;
  100.     for(i = 1; i <= R; i++) {
  101.         std::string s(C, '#');
  102.         cin >> s;
  103.         for(j = 1; j <= C; j++) {
  104.             if(s[j-1] == '#') {
  105.                 mp[i][j] = ++V;
  106.                 posX[V] = i, posY[V] = j;
  107.             }
  108.         }
  109.     }
  110.     for (n = i = 1; i <= R; ++i, ++n)
  111.         for (j = 1; j < C; ++j, ++n)
  112.             if (mp[i][j] && mp[i][j+1])
  113.                 addedge(mp[i][j], mp[i][j+1]);
  114.     for (n = i = 1; i < R; ++i)
  115.         for (j = 1; j <= C; ++j, ++n)
  116.             if (mp[i][j] && mp[i+1][j])
  117.                 addedge(mp[i][j], mp[i+1][j]);
  118.     std::iota(p + 1, p + (V + 1), 1);
  119.     for (i = 1; i <= E; i += 2)
  120.         if (!join(e[i].u, e[i].v)) {
  121.             orient[i] = orient[i + 1] = i;
  122.             //          fprintf(stderr, "%d %d\n", e[i].u, e[i].v);
  123.         }
  124.     Planar::main();
  125.     std::vector<std::tuple<int,int,int>> mat;
  126.     for (i = 1; i <= E; ++i) if (orient[i] == i) {
  127.         mat.eb(e[i].u-1, e[i].v-1, 1);
  128.         mat.eb(e[i].v-1, e[i].u-1, -1);
  129.     }
  130.     std::cerr << "Matrix constructed success\n";
  131.     std::cerr << V << ' ' << mat.size() << '\n';
  132.     std::cout << V << ' ' << mat.size() << '\n';
  133.     for(auto [a, b, c]: mat)
  134.         std::cout << a << ' '<< b << ' ' << c << '\n';
  135.     return 0;
  136. }
Advertisement
Add Comment
Please, Sign In to add comment