답안 #296333

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
296333 2020-09-10T13:38:12 Z ToMmyDong Simurgh (IOI17_simurgh) C++17
0 / 100
1 ms 512 KB
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<double, double> pdd;
#define SQ(i) ((i)*(i))
#define MEM(a, b) memset(a, (b), sizeof(a))
#define SZ(i) static_cast<int>(i.size())
#define FOR(i, j, k, in) for (int i=j; i < (k) ; i+=in)
#define RFOR(i, j, k, in) for (int i=j; i >= (k) ; i-=in)
#define REP(i, j) FOR(i, 0, j, 1)
#define REP1(i, j) FOR(i, 1, j+1, 1)
#define RREP(i, j) RFOR(i, j, 0, 1)
#define ALL(_a) _a.begin(), _a.end()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define X first
#define Y second
template<typename T, typename S>
istream &operator >> (istream &is, pair<T, S> &p) {
    return is >> p.X >> p.Y;
}
#ifdef tmd
#define TIME(i) Timer i(#i)
#define debug(...) do {\
    fprintf(stderr, "%s - %d (%s) = ", __PRETTY_FUNCTION__, __LINE__, #__VA_ARGS__);\
    _do(__VA_ARGS__);\
}while(0)
template<typename T> void _do(T &&_x) {cerr<<_x<<endl;}
template<typename T,typename ...S> void _do(T &&_x, S &&..._t) {cerr <<_x <<" ,"; _do(_t...);}
template<typename _a,typename _b> ostream& operator << (ostream &_s, const pair<_a, _b> &_p) {return _s << "(" << _p.X << "," << _p.Y << ")";}
template<typename It> ostream& _OUTC(ostream &_s, It _ita, It _itb)
{
    _s << "{";
    for (It _it=_ita; _it != _itb; _it++) {
        _s <<(_it == _ita?"":",")<< *_it;
    }
    _s << "}";
    return _s;
}
template<typename _a> ostream &operator << (ostream &_s, const vector<_a> &_c) {return _OUTC(_s,ALL(_c));}
template<typename _a> ostream &operator << (ostream &_s, const array<_a,2> &_c) {return _OUTC(_s, ALL(_c));}
template<typename _a> ostream &operator << (ostream &_s, const array<_a,3> &_c) {return _OUTC(_s, ALL(_c));}
template<typename _a> ostream &operator << (ostream &_s, const array<_a,4> &_c) {return _OUTC(_s, ALL(_c));}
template<typename _a> ostream &operator << (ostream &_s, const array<_a,5> &_c) {return _OUTC(_s, ALL(_c));}
template<typename _a> ostream &operator << (ostream &_s, const set<_a> &_c) {return _OUTC(_s, ALL(_c));}
template<typename _a> ostream &operator << (ostream &_s, const deque<_a> &_c) {return _OUTC(_s, ALL(_c));}
template<typename _a,typename _b> ostream &operator << (ostream &_s, const map<_a,_b> &_c) {return _OUTC(_s,ALL(_c));}
template<typename _t> void pary(_t _a,_t _b){_OUTC(cerr,_a,_b);cerr<<endl;}
#define IOS()
class Timer {
private:
    string scope_name;
    chrono::high_resolution_clock::time_point start_time;
public:
    Timer (string name) : scope_name(name) {
        start_time = chrono::high_resolution_clock::now();
    }
    ~Timer () {
        auto stop_time = chrono::high_resolution_clock::now();
        auto length = chrono::duration_cast<chrono::microseconds>(stop_time - start_time).count();
        double mlength = double(length) * 0.001;
        debug(scope_name, mlength);
    }
};
#else
#define TIME(i)
#define debug(...)
#define pary(...)
#define endl '\n'
#define IOS() ios_base::sync_with_stdio(0);cin.tie(0)
#endif
#include "simurgh.h"

int n, dfs_time;
vector<vector<pii> > edge;
vector<int> fat, fid, dfn;
vector<pii> low, G;

vector<int> tree;
vector<int> gold;
void dfs (int nd, int par) {
    dfn[nd] = dfs_time++;
    low[nd] = {dfn[nd], -1};
    for (auto &[u,id] : edge[nd]) {
        if (u == par) continue;
        if (dfn[u] == -1) { // tree
            fat[u] = nd;
            fid[u] = id;
            dfs(u, nd);
            low[nd] = min(low[nd], low[u]);
            tree.eb(id);
        } else if (dfn[u] < dfn[nd]) {
            low[nd] = min(low[nd], pii(dfn[u], id));
        }
    }
    if (low[nd].X == dfn[nd]) {
        gold[fid[nd]] = 1;
    }
}

struct Djs {
    vector<int> djs;
    Djs(int N) : djs(N) {
        iota(ALL(djs), 0);
    }
    int fnd (int x) {
        return x == djs[x] ? x : djs[x] = fnd(djs[x]);
    }
    bool mrg (int x, int y) {
        x = fnd(x), y = fnd(y);
        if (x == y) return false;
        djs[fnd(x)] = fnd(y);
        return true;
    }
};

void build_cycle (vector<int> cycle) {
    vector<int> res;
    debug(cycle);
    for (int i=0; i<SZ(cycle); i++) {
        Djs djs(n);
        vector<int> qry;
        for (int j=0; j<SZ(cycle); j++) {
            if (i != j) {
                qry.eb(cycle[j]);
                assert(djs.mrg(G[cycle[j]].X, G[cycle[j]].Y));
            }
        }
        for (int id : tree) {
            if (djs.mrg(G[id].X, G[id].Y)) {
                qry.eb(id);
            }
        }
        res.eb(count_common_roads(qry));
    }

    debug(res);
    int mn = *max_element(ALL(res));
    for (int i=0; i<SZ(cycle); i++) {
        gold[cycle[i]] = (res[i] == mn) ? -1 : 1;
    }
}

void build_alt (vector<int> cycle, int known, int want) {

    vector<int> res;
    debug(cycle, known, want);
    for (int i : {known, want}) {
        Djs djs(n);
        vector<int> qry;
        for (int j=0; j<SZ(cycle); j++) {
            if (i != cycle[j]) {
                qry.eb(cycle[j]);
                assert(djs.mrg(G[cycle[j]].X, G[cycle[j]].Y));
            }
        }
        for (int id : tree) {
            if (djs.mrg(G[id].X, G[id].Y)) {
                qry.eb(id);
            }
        }
        res.eb(count_common_roads(qry));
    }

    gold[want] = gold[known] * ((res[0] == res[1]) ? 1 : -1);
}

void check (int id) {
    if (gold[id]) return;
    int be = low[G[id].Y].Y;
    int nd = G[be].Y;
    vector<int> cycle = {be};

    int known = -1;
    while (nd != G[be].X) {
        if (gold[fid[nd]]) known = fid[nd];
        cycle.eb(fid[nd]);
        nd = fat[nd];
    }
    
    if (known == -1) build_cycle(cycle);
    else build_alt(cycle, known, id);
}

void bin_gold (int nd) {
    int cnt = 0;
    while (cnt < SZ(edge[nd])) {
        int L = 0, R = SZ(edge[nd]) + 1;
        while (L < R - 1) {
            int M = (L + R) >> 1;
            vector<int> qry;
            Djs djs(n);
            for (int i=0; i<M; i++) {
                qry.eb(edge[nd][i].Y);
                assert(djs.mrg(edge[nd][i].X, nd)); 
            }
            int tree_gold = 0;
            for (int id : tree) {
                if (djs.mrg(G[id].X, G[id].Y)) {
                    tree_gold += gold[id] == 1;
                    qry.eb(id);
                }
            }

            int sum = count_common_roads(qry) - tree_gold;
            if (sum > cnt) R = M;
            else L = M;
        }
        debug(nd, cnt, R);
        if (R == SZ(edge[nd]) + 1) break;
        else gold[edge[nd][R-1].Y] = true;
        cnt++;
    }
}

std::vector<int> find_roads(int N, std::vector<int> u, std::vector<int> v) {
    n = N;
    dfs_time = 0;
    edge.resize(n);
    fat.resize(n);
    fid.resize(n);
    low.resize(n);
    dfn.resize(n, -1);
    gold.resize(SZ(u));
    for (int i=0; i<SZ(u); i++) {
        edge[u[i]].eb(v[i], i);
        edge[v[i]].eb(u[i], i);
        G.eb(v[i], u[i]);
    }
    debug(N, G);
    dfs(0, -1);
    for (int id=0; id<SZ(G); id++) {
        if (dfn[G[id].X] > dfn[G[id].Y]) {
            swap(G[id].X, G[id].Y);
        }
    }

    for (int id : tree) {
        check(id);
        debug(id, gold[id]);
        //6353
        //IHTT_216916
    }

    for (int i=0; i<n; i++) {
        bin_gold(i);
    }
    debug(gold);

    vector<int> ans;
    for (int i=0; i<SZ(G); i++) {
        if (gold[i] == 1) ans.eb(i);
    }
    assert(ans.size() == n-1);
    return ans;

}

Compilation message

In file included from /usr/include/c++/9/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/9/bits/stdc++.h:33,
                 from simurgh.cpp:2:
simurgh.cpp: In function 'std::vector<int> find_roads(int, std::vector<int>, std::vector<int>)':
simurgh.cpp:260:23: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  260 |     assert(ans.size() == n-1);
      |            ~~~~~~~~~~~^~~~~~
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 512 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 512 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 512 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 256 KB correct
2 Runtime error 1 ms 512 KB Execution killed with signal 11
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1 ms 512 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -