Submission #976120

#TimeUsernameProblemLanguageResultExecution timeMemory
976120efedmrlrConnecting Supertrees (IOI20_supertrees)C++17
21 / 100
178 ms22400 KiB
// #pragma GCC optimize("O3,Ofast,unroll-loops")
// #pragma GCC target("avx2,bmi,popcnt")
#include <bits/stdc++.h>
#include "supertrees.h"


#define lli long long int
#define ld long double
#define REP(i, n) for(int i = 0; (i) < (n); (i)++)
#define all(x) x.begin(), x.end();
#define rall(x) x.rbegin(), x.rend()
#define pb push_back
#define MP make_pair

using namespace std;

void fastio() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
}

const int N = 1e5 + 5;
const int INF = 1e9 + 500;
const int MOD = 1e9 + 7;

struct DSU {
    vector<int> p, sz, typ;
    int n;
    void make_set(int x) {
        p[x] = x;
        sz[x] = 1;
    }
    void init(int nn) {
        n = nn;
        p.assign(n + 3, 0);
        sz.assign(n + 3, 0);
        typ.assign(n + 3, 0);
        for(int i = 0; i < n; i++) {
            make_set(i);
        }
    }
    int find_set(int x) {
        return (x == p[x]) ? x : p[x] = find_set(p[x]);
    }
    bool union_set(int x, int y) {
        x = find_set(x); y = find_set(y);
        if(x == y) return 0;
        if(sz[x] < sz[y]) swap(x, y);
        sz[x] += sz[y];
        p[y] = x;
        return 1;
    }
};

int construct(std::vector<std::vector<int>> p) {
	int n = (int)p.size();
	vector<vector<int> > ans(n, vector<int>(n, 0));
    DSU ds, ds2;
    ds.init(n);

    // check zero
    bool f = 1;
    for(int i = 0; i < n; i++) {
        for(int j = i + 1; j < n; j++) {
            if(p[i][j]) {
                ds.union_set(i, j);
            }
        }
    }
    for(int i = 0; i < n; i++) {
        for(int j = i + 1; j < n; j++) {
            if(!p[i][j] && ds.find_set(i) == ds.find_set(j)) {
                f = 0;
            }
        }
    }
    if(!f) return 0;
    // cerr << "zort" << endl;
    ds.init(n);
    
    for(int i = 0; i < n; i++) {
        for(int j = i + 1; j < n; j++) {
            if(p[i][j] == 1) {
                ds.union_set(i, j);
            }
        }
    }
    for(int i = 0; i < n; i++) {
        if(ds.sz[ds.find_set(i)] > 1) {
            ds.typ[i] = 1; 
        }
    }
    for(int i = 0; i < n; i++) {
        for(int j = i + 1; j < n; j++) {
            if(p[i][j] == 2 && !ds.typ[i] && !ds.typ[j]) {
                ds.union_set(i, j);
            }
        }
    }
    vector<vector<int> > comp(n, vector<int>());
    for(int i = 0; i < n; i++) {
        comp[ds.find_set(i)].pb(i);
    }
    
    for(int i = 0; i < n; i++) {
        for(int j = i + 1; j < n; j++) {
            if(ds.find_set(i) != i || ds.find_set(j) != j) continue;
            
            if(ds.typ[i] == ds.typ[j]) continue;
            if(p[i][j] != 2) continue; 
            int x = i, y = j;
            if(ds.typ[x]) swap(x, y);
            comp[x].pb(y); 
        } 
    }
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < (int)comp[i].size() - 1; j++) {
            ans[comp[i][j]][comp[i][j + 1]] = 1;
            ans[comp[i][j + 1]][comp[i][j]] = 1;
        }
        if((int)comp[i].size() > 1 && !ds.typ[i]) {
            ans[comp[i].back()][comp[i][0]] = 1;
            ans[comp[i][0]][comp[i].back()] = 1;
        }
    }
    if(!f) 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...