답안 #56082

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
56082 2018-07-09T21:53:06 Z Benq Simurgh (IOI17_simurgh) C++14
0 / 100
2 ms 440 KB
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
 
using namespace std;
using namespace __gnu_pbds;
 
typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;
 
typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;
 
typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;
 
template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;
 
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
 
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()
 
const int MOD = 1000000007;
const ll INF = 1e18;
const int MX = 100001;
 
#include "simurgh.h"
 
template<int SZ> struct DSU {
    int par[SZ], sz[SZ];
    DSU() {
        F0R(i,SZ) par[i] = i, sz[i] = 1;
    }
    
    int get(int x) { // path compression
    	if (par[x] != x) par[x] = get(par[x]);
    	return par[x];
    }
    
    bool unite(int x, int y) { // union-by-rank
    	x = get(x), y = get(y);
    	if (x == y) return 0;
    	if (sz[x] < sz[y]) swap(x,y);
    	sz[x] += sz[y], par[y] = x;
    	return 1;
    }
};

int N;
vpi ed;
set<int> yes, maybe;
 
/*int sec[500*499/2];
int co;
 
int count_common_roads(vi z) {
    co ++;
    assert(sz(z) == N-1);
    DSU<500> D = DSU<500>();
    int ret = 0;
    for (int i: z) {
        if (!D.unite(ed[i].f,ed[i].s)) exit(5);
        if (sec[i]) ret ++;
    }
    return ret;
}*/

vpi ctree;
vpi adj[500];
pi par[500];
int depth[500], status[30000]; // 1 = in, -1 = not

int query(vi x) {
    DSU<500> D; for (int i: x) D.unite(ed[i].f,ed[i].s);
    int ad = 0;
    for (auto a: ctree) if (D.unite(ed[a.f].f,ed[a.f].s)) {
        ad += a.s;
        x.pb(a.f);
    }
    return count_common_roads(x)-ad;
}

void genDepth(int cur) {
    depth[cur] = depth[par[cur].f]+1;
    for (auto a: adj[cur]) if (a.f != par[cur].f) {
        par[a.f] = {cur,a.s};
        genDepth(a.f);
    }
}

void check(int x) {
    int a = ed[x].f, b = ed[x].s;
    vi tmp = {x};
    bool need = 0;
    while (a != b) {
        if (depth[a] < depth[b]) swap(a,b);
        tmp.pb(par[a].s);
        if (status[par[a].s] == 0) need = 1;
        a = par[a].f;
    }
    if (!need || sz(tmp) == 2) return;
    int mx = -MOD;
    
    for (int i: tmp) if (status[i] != 0) {
        vi v;
        for (int j: tmp) if (j != i) v.pb(j);
        mx = query(v);
        if (status[i] == 1) mx ++;
        break;
    }
    
    vpi TMP;
    for (int i: tmp) if (status[i] == 0) {
        vi v;
        for (int j: tmp) if (j != i) v.pb(j);
        int t = query(v);
        mx = max(mx,t);
        TMP.pb({t,i});
    }
    
    for (auto a: TMP) {
        if (a.f < mx) {
            status[a.s] = 1;
        } else {
            status[a.s] = -1;
        }
    }
}

void addEdge(int x) {
    adj[ed[x].f].pb({ed[x].s,x});
    adj[ed[x].s].pb({ed[x].f,x});
    ctree.pb({x,0});
}

void init() {
    DSU<500> D;
    for (int i: maybe) if (D.unite(ed[i].f,ed[i].s)) addEdge(i);
    genDepth(0);
    for (int i: maybe) check(i);
    for (auto& a: ctree) {
        maybe.erase(a.f);
        if (status[a.f] == 0) status[a.f] = 1;
        a.s = (status[a.f]+1)/2;
        if (a.s) yes.insert(a.f);
        //cout << a.f << " " << a.s << "\n";
    }
    //exit(0);
}

void search(vi x, int num) {
    if (num == 0) {
        return;
    }
    if (num == sz(x)) {
        for (int i: x) yes.insert(i);
        return;
    }
    vi X = vi(x.begin(),x.begin()+sz(x)/2);
    int n1 = query(x);
    search(X,n1);
    search(vi(x.begin()+sz(x)/2,x.end()),num-n1);
}
 
vector<int> find_roads(int n, vi u, vi v) {
    N = n;
    ed.resize(sz(u));
    F0R(i,sz(u)) {
        ed[i].f = u[i], ed[i].s = v[i];
        maybe.insert(i);
    }
    
    init();
    
    while (sz(yes) < n-1) {
        DSU<500> D;
        vi tmp;
        for (int x: maybe) if (D.unite(ed[x].f,ed[x].s)) tmp.pb(x);
        for (int x: tmp) maybe.erase(x);
        /*for (int x: tmp) cout << x << " ";
        cout << '\n';
        co ++;
        if ()*/
        search(tmp, query(tmp));
    }
    
    vi ans; for (int i: yes) ans.pb(i);
    return ans;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 2 ms 376 KB WA in grader: NO
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 2 ms 376 KB WA in grader: NO
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 2 ms 376 KB WA in grader: NO
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 376 KB correct
2 Incorrect 2 ms 440 KB WA in grader: NO
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 2 ms 376 KB WA in grader: NO
2 Halted 0 ms 0 KB -