Advertisement
erek1e

IOI '20 - Supertrees

Mar 5th, 2023
614
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.34 KB | None | 0 0
  1. #include "supertrees.h"
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6. int construct(vector<vector<int>> p) {
  7.     int n = p.size();
  8.     for (int i = 0; i < n; ++i) {
  9.         for (int j = 0; j < n; ++j) {
  10.             if (p[i][j] == 3) return 0;
  11.         }
  12.     }
  13.  
  14.     // Split into components
  15.     vector<vector<int>> components;
  16.     vector<int> myCmp(n, -1);
  17.     for (int i = 0; i < n; ++i) {
  18.         if (myCmp[i] != -1) continue;
  19.         components.push_back({});
  20.         for (int j = 0; j < n; ++j) {
  21.             if (p[i][j]) {
  22.                 if (myCmp[j] != -1) return 0;
  23.                 components.back().push_back(j);
  24.                 myCmp[j] = (int)components.size()-1;
  25.             }
  26.         }
  27.     }
  28.  
  29.     // Check components are separate
  30.     for (int i = 0; i < n; ++i) {
  31.         for (int j = 0; j < n; ++j) {
  32.             if ((myCmp[i] == myCmp[j]) ^ (p[i][j] != 0)) return 0;
  33.         }
  34.     }
  35.  
  36.     // Build answer here
  37.     vector<vector<int>> edge(n, vector<int>(n));
  38.  
  39.     // Now solve separately for each component
  40.     for (vector<int> &c : components) {
  41.         // Split into 1-chains
  42.         vector<vector<int>> chains;
  43.         vector<int> myChain(n, -1);
  44.         for (int i : c) {
  45.             if (myChain[i] != -1) continue;
  46.             chains.push_back({});
  47.             for (int j : c) {
  48.                 if (p[i][j] == 1) {
  49.                     if (myChain[j] != -1) return 0;
  50.                     chains.back().push_back(j);
  51.                     myChain[j] = (int)chains.size()-1;
  52.                 }
  53.             }
  54.         }
  55.  
  56.         // Check 1-chains are separate
  57.         for (int i : c) {
  58.             for (int j : c) {
  59.                 if ((myChain[i] == myChain[j]) ^ (p[i][j] == 1)) return 0;
  60.             }
  61.         }
  62.  
  63.         // Assign a chain leader to each chain
  64.         int m = chains.size();
  65.         vector<int> chainLeader(m);
  66.         for (int i = 0; i < m; ++i) chainLeader[i] = chains[i][0];
  67.        
  68.         // Check chains and their leaders behave in the same way
  69.         for (int i : c) {
  70.             for (int j : c) {
  71.                 if (p[i][j] != p[chainLeader[myChain[i]]][j]) return 0;
  72.             }
  73.         }
  74.  
  75.         // There will be two ways to travel between a pair of nodes in different chains
  76.         if (m == 2) return 0; // cannot have two chains (cannot make cycle)
  77.  
  78.         // Connect within chains
  79.         for (int i : c) {
  80.             if (chainLeader[myChain[i]] != i) {
  81.                 edge[i][chainLeader[myChain[i]]] = edge[chainLeader[myChain[i]]][i] = 1;
  82.             }
  83.         }
  84.  
  85.         // Connect chain leaders in a cycle
  86.         if (m == 1) continue; // only one chain - no need
  87.         for (int i = 0; i < m; ++i) {
  88.             int j = (i+1)%m;
  89.             edge[chainLeader[i]][chainLeader[j]] = edge[chainLeader[j]][chainLeader[i]] = 1;
  90.         }
  91.     }
  92.  
  93.     build(edge);
  94.     return 1;
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement