Advertisement
BaoJIaoPisu

Untitled

Dec 2nd, 2021
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.05 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. #define pb push_back
  5. #define pf push_front
  6. #define popb pop_back
  7. #define popf pop_front
  8. #define ins insert
  9. #define pq priority_queue
  10. #define minele min_element
  11. #define maxele max_element
  12. #define mp make_pair
  13. #define lb lower_bound //first pos >= val
  14. #define ub upper_bound // first pos > val
  15. #define cnt_bit __builtin_popcount
  16. #define all(x) x.begin(), x.end()
  17. #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
  18. //#pragma GCC optimize("Ofast")
  19. //#pragma GCC target("avx,avx2,fma")
  20. using namespace std;
  21.  
  22. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  23.  
  24. typedef long long ll;
  25. typedef unsigned long long ull;
  26. typedef pair<ll, ll> pll;
  27. typedef pair<int, int> pii;
  28.  
  29. int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
  30. int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
  31. int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
  32.  
  33. int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
  34. int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
  35.  
  36. const int INF = 1e9;
  37. const ll oo = 1e18;
  38. const ll maxN = 1e6;
  39.  
  40. /* Author : Le Ngoc Bao Anh, 11A5, LQD High School for Gifted Student */
  41.  
  42. struct Dinitz {
  43.     struct Edges {
  44.         int u, v;
  45.         ll cap;
  46.  
  47.         Edges() : u(), v(), cap() {}
  48.         Edges(int _u, int _v, ll _cap) : u(_u), v(_v), cap(_cap) {}
  49.     };
  50.  
  51.     vector<vector<int>> g;
  52.     vector<Edges> ed;
  53.     vector<int> dist;
  54.     vector<int> id;
  55.     int S, T;
  56.     int n;
  57.  
  58.     Dinitz() : ed(), n(), S(), T() {}
  59.     Dinitz(int _n, int _S, int _T) {
  60.         n = _n; S = _S; T = _T;
  61.         g.resize(n);
  62.         dist.resize(n);
  63.         id.resize(n);
  64.         for(int i = 0; i < n; i++) g[i].clear();
  65.         ed = vector<Edges>();
  66.     }
  67.  
  68.     void addEdge(int u, int v, ll cap) {
  69.         g[u].pb((int)ed.size());
  70.         ed.pb(Edges(u, v, cap));
  71.         g[v].pb((int)ed.size());
  72.         ed.pb(Edges(v, u, 0));
  73.     }
  74.  
  75.     bool bfs() {
  76.         for(int i = 0; i < n; i++) dist[i] = n + 5;
  77.         queue<int> q;
  78.         q.push(S); dist[S] = 0;
  79.         while(!q.empty()) {
  80.             int u = q.front(); q.pop();
  81.             for(int i : g[u]) {
  82.                 Edges e = ed[i];
  83.                 if(!e.cap) continue;
  84.                 if(dist[e.v] <= dist[u] + 1) continue;
  85.                 dist[e.v] = dist[u] + 1;
  86.                 q.push(e.v);
  87.             }
  88.         }
  89.  
  90.         return dist[T] < n + 5;
  91.     }
  92.  
  93.     ll dfs(int u, ll flow) {
  94.         if(u == T || flow == 0) return flow;
  95.  
  96.         ll ans = 0;
  97.         for(int &i = id[u]; i < (int)g[u].size(); i++) {
  98.             Edges e = ed[g[u][i]];
  99.             if(!e.cap) continue;
  100.             if(dist[e.v] != dist[u] + 1) continue;
  101.             ll f = dfs(e.v, min(flow, e.cap));
  102.             flow -= f;
  103.             ans += f;
  104.             ed[g[u][i]].cap -= f;
  105.             ed[g[u][i] ^ 1].cap += f;
  106.             if(flow == 0) return ans;
  107.         }
  108.  
  109.         return ans;
  110.     }
  111.  
  112.     ll Flow() {
  113.         ll ans = 0;
  114.         while(bfs()) {
  115.             for(int i = 0; i < n; i++) id[i] = 0;
  116.             ans += dfs(S, oo);
  117.         }
  118.  
  119.         return ans;
  120.     }
  121.  
  122.     vector<pii> getEdge() {
  123.         vector<pii> ans;
  124.         for(int i = 0; i < ed.size(); i++) {
  125.             int u = ed[i].u, v = ed[i].v;
  126.             if(u == S || v == S || u == T || v == T) continue;
  127.             if(!(u & 1)) continue;
  128.             if(!ed[i].cap) ans.pb(make_pair(u, v));
  129.         }
  130.  
  131.         return ans;
  132.     }
  133. };
  134.  
  135. struct TWOSAT {
  136.     int n;
  137.     vector<vector<int>> g;
  138.     vector<vector<int>> ed;
  139.     vector<int> Num;
  140.     vector<int> Low;
  141.     vector<int> idComp;
  142.     vector<bool> visited;
  143.     stack<int> st;
  144.     vector<int> ord;
  145.     vector<int> idSort;
  146.     int Time, cntComp;
  147.  
  148.     TWOSAT(int _n = 0) {
  149.         n = _n;
  150.         g.resize(2 * n + 2);
  151.         ed.resize(2 * n + 2);
  152.         Num.resize(2 * n + 2);
  153.         Low.resize(2 * n + 2);
  154.         visited.resize(2 * n + 2);
  155.         idComp.resize(2 * n + 2);
  156.         idSort.resize(2 * n + 2);
  157.         ord.clear();
  158.         Time = cntComp = 0;
  159.  
  160.         for(int i = 1; i <= 2 * n; i++) {
  161.             g[i].clear(); ed[i].clear();
  162.             idSort[i] = Num[i] = visited[i] = Low[i] = idComp[i] = 0;
  163.         }
  164.     }
  165.  
  166.     int NOT(int u) {
  167.         return (u > n ? u - n : u + n);
  168.     }
  169.  
  170.     void Connect(int u, int v) {
  171.         g[u].pb(v);
  172.     }
  173.  
  174.     void addEdge(int u, int v) {
  175.         // u || v = 1
  176.         Connect(NOT(u), v);
  177.         Connect(NOT(v), u);
  178.     }
  179.  
  180.     void tarjan(int u) {
  181.         Num[u] = Low[u] = ++Time;
  182.         st.push(u);
  183.  
  184.         for(auto v : g[u]) {
  185.             if(Num[v]) {
  186.                 Low[u] = min(Low[u], Num[v]);
  187.             } else {
  188.                 tarjan(v);
  189.                 Low[u] = min(Low[u], Low[v]);
  190.             }
  191.         }
  192.  
  193.         if(Num[u] == Low[u]) {
  194.             int v = 0;
  195.             ++cntComp;
  196.             do {
  197.                 v = st.top(); st.pop();
  198.                 idComp[v] = cntComp;
  199.                 Num[v] = Low[v] = INF;
  200.             } while(v != u);
  201.         }
  202.     }
  203.  
  204.     void topo(int u) {
  205.         visited[u] = true;
  206.         for(auto v : ed[u]) {
  207.             if(!visited[v]) topo(v);
  208.         }
  209.  
  210.         ord.pb(u);
  211.     }
  212.  
  213.     vector<int> do2SAT() {
  214.         for(int i = 1; i <= 2 * n; i++) {
  215.             if(!Num[i]) tarjan(i);
  216.         }
  217.  
  218.         for(int i = 1; i <= n; i++) {
  219.             if(idComp[i] == idComp[i + n]) return {-1};
  220.         }
  221.  
  222.         vector<int> ans;
  223.         for(int i = 1; i <= 2 * n; i++) {
  224.             int u = idComp[i];
  225.             for(auto v : g[i]) {
  226.                 v = idComp[v];
  227.                 if(u == v) continue;
  228.                 ed[u].pb(v);
  229.             }  
  230.         }
  231.  
  232.         for(int i = 1; i <= 2 * n; i++) {
  233.             if(!visited[i]) topo(i);
  234.         }
  235.         reverse(all(ord));
  236.  
  237.         for(int i = 0; i < 2 * n; i++) idSort[ord[i]] = i + 1;
  238.  
  239.         for(int i = 1; i <= n; i++) {
  240.             int u = idComp[i], v = idComp[i + n];
  241.             if(idSort[u] > idSort[v]) ans.pb(i);
  242.         }
  243.  
  244.         return ans;
  245.     }
  246. };
  247.  
  248. const int N = 105;
  249. bool banned[N][N];
  250. bool ok[N * N];
  251.  
  252. void solve() {
  253.     int n, m, k; cin >> n >> m >> k;
  254.     for(int i = 1; i <= k; i++) {
  255.         int x, y; cin >> x >> y;
  256.         banned[x][y] = true;
  257.     }
  258.  
  259.     auto node = [&](int i, int j) -> int {
  260.         return (i - 1) * m + j;
  261.     };
  262.  
  263.     auto inside = [&](int i, int j) -> bool {
  264.         return (i > 0 && j > 0 && i <= n && j <= m && !banned[i][j]);
  265.     };
  266.  
  267.     Dinitz G = Dinitz(n * m + 5, 0, n * m + 1);
  268.     for(int i = 1; i <= n; i++) {
  269.         for(int j = 1; j <= m; j++) {
  270.             if(banned[i][j]) continue;
  271.             if(node(i, j) & 1) G.addEdge(0, node(i, j), 1);
  272.             else G.addEdge(node(i, j), n * m + 1, 1);
  273.         }
  274.     }
  275.  
  276.     TWOSAT S = TWOSAT(n * m);
  277.     for(int i = 1; i <= n; i++) {
  278.         for(int j = 1; j <= m; j++) {
  279.             if(!(node(i, j) & 1) || banned[i][j]) continue;
  280.             for(int r = 0; r < 8; r++) {
  281.                 int x = i + dx[r], y = j + dy[r];
  282.                 if(!inside(x, y)) continue;
  283.                 G.addEdge(node(i, j), node(x, y), 1);
  284.                 S.addEdge(node(i, j), node(x, y));
  285.             }
  286.         }
  287.     }
  288.  
  289.     int flow = G.Flow();
  290.     vector<pii> mf = G.getEdge();
  291.  
  292.     int numNodes = n * m;
  293.     for(int i = 0; i < mf.size(); i++) {
  294.         int u = mf[i].fi, v = mf[i].se;
  295.         ok[u] = ok[v] = true;
  296.         S.addEdge(u + numNodes, v + numNodes);
  297.     }
  298.  
  299.     for(int i = 1; i <= n * m; i++) {
  300.         if(!ok[i]) S.addEdge(i + numNodes, i + numNodes);
  301.     }
  302.  
  303.     vector<int> notChosen = S.do2SAT();
  304.  
  305.     for(int i = 0; i < notChosen.size(); i++) {
  306.         int id = notChosen[i];
  307.         int u = (id - 1) / m + 1, v = (id - 1) % m + 1;
  308.         banned[u][v] = true;
  309.     }
  310.  
  311.     vector<pii> ans;
  312.     for(int i = 1; i <= n; i++) {
  313.         for(int j = 1; j <= m; j++) {
  314.             if(!banned[i][j]) ans.pb(make_pair(i, j));
  315.         }
  316.     }
  317.  
  318.     cout << ans.size() << '\n';
  319.     for(int i = 0; i < ans.size(); i++) {
  320.         cout << ans[i].fi << " " << ans[i].se << '\n';
  321.     }
  322. }
  323.  
  324. int main()
  325. {
  326.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  327.     #ifndef ONLINE_JUDGE
  328.     freopen("input.txt", "r", stdin);
  329.     freopen("output.txt", "w", stdout);
  330.     #else
  331.     //online
  332.     #endif
  333.  
  334.     int tc = 1, ddd = 0;
  335.     // cin >> tc;
  336.     while(tc--) {
  337.         //ddd++;
  338.         //cout << "Case #" << ddd << ": ";
  339.         solve();
  340.     }
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement