Submission #561634

#TimeUsernameProblemLanguageResultExecution timeMemory
561634senthetaConnecting Supertrees (IOI20_supertrees)C++17
100 / 100
256 ms28232 KiB
#include "supertrees.h" // author : sentheta aka vanwij #include<iostream> #include<iomanip> #include<algorithm> #include<cassert> #include<random> #include<chrono> #include<cmath> #include<string> #include<vector> #include<bitset> #include<queue> #include<stack> #include<map> #include<set> using namespace std; #define Int long long #define V vector #define pb push_back #define pii pair<int,int> #define ff first #define ss second #define rand() (uniform_int_distribution<int>(0,1<<30)(rng)) mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); #define pow2(x) (1LL<<(x)) #define msb(x) (63-__builtin_clzll(x)) #define bitcnt(x) (__builtin_popcountll(x)) #define nl '\n' #define _ << ' ' << #define dbg(x) cout<<"?"<< #x <<" : "<<(x)<<endl; cout.flush(); #define rep(i,a,b) for(int i = (int)(a); i < (int)(b); i++) #define all(x) (x).begin(), (x).end() const int N = 1005; struct Dsu{ int p[N]; V<int> v[N]; void reset(){ rep(i,0,N){ p[i] = -1; v[i] = {i}; } } int find(int x){ if(p[x]==-1) return x; return p[x] = find(p[x]); } bool same(int x,int y){ return find(x)==find(y); } void unite(int x,int y){ if((x=find(x))==(y=find(y))) return; // wlog sz(x) > sz(y) if(v[x].size() < v[y].size()) swap(x,y); p[y] = x; for(int i : v[y]) v[x].pb(i); v[y].clear(); } } dsu, t; int n; V<V<int>> ans, p; void make_edge(int x,int y){ ans[x][y] = ans[y][x] = 1; } bool f(V<int>& v){ int sz = v.size(); bool two = false, tri = false; for(int x : v) for(int y : v){ two |= p[x][y]==2; tri |= p[x][y]==3; } if(two && tri) return false; // straight path if(!two && !tri){ rep(i,1,sz){ make_edge(v[i], v[i-1]); } return true; } // cycle grouping for(int x : v) for(int y : v){ if(p[x][y] == 1){ t.unite(x,y); } } // find main cycle V<int> lead; for(int x : v) if(t.find(x)==x){ lead.pb(x); } if(lead.size() <= 2) return false; if(tri) return false; //if(tri && lead.size()<=3) return false; // make main cycle rep(i,0,lead.size()){ make_edge(lead[i], lead[(i+1)%lead.size()]); } if(tri){ make_edge(lead[0], lead[2]); } // group of each nodes for(int x : lead){ for(int y : t.v[x]) if(y != x){ make_edge(x, y); } } return true; } int construct(V<V<int>> _p) { p = _p; n = p.size(); dsu.reset(); t.reset(); ans = V<V<int>>(n,V<int>(n)); // connected components rep(i,0,n) rep(j,0,i) if(p[i][j]){ dsu.unite(i,j); } rep(i,0,n) rep(j,0,i) if(dsu.same(i,j)){ if(p[i][j] == 0) return 0; } // solve per cc rep(i,0,n) if(dsu.find(i) == i){ if(!f(dsu.v[i])) return 0; } build(ans); return 1; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...