Submission #594571


Source Code Expand

#define _CRT_SECURE_NO_WARNINGS
//#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//#define int ll
//#define endl "\n"
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i,a,b) for(ll i=a; i<ll(b); i++)
#define rep(i,b) loop(i,0,b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template<class T> ostream & operator<<(ostream & os, vector<T> const &);
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":" ") << get<n>(t); _ot<n+1>(os, t); }
    template<class...T> ostream & operator<<(ostream & os, tuple<T...> const & t){ _ot<0>(os, t); return os; }
template<class T, class U> ostream & operator<<(ostream & os, pair<T,U> const & p){ return os << "(" << p.first << ", " << p.second << ") "; }
template<class T> ostream & operator<<(ostream & os, vector<T> const & v){ rep(i,v.size()) os << v[i] << (i+1==(int)v.size()?"":" "); return os; }
template<class T> inline bool chmax(T & x, T const & y){ return x<y ? x=y,true : false; }
template<class T> inline bool chmin(T & x, T const & y){ return x>y ? x=y,true : false; }
#ifdef DEBUG
#define dump(...) (cerr<<#__VA_ARGS__<<" = "<<mt(__VA_ARGS__)<<" ["<<__LINE__<<"]"<<endl)
#else
#define dump(...)
#endif
// ll const mod = 1000000007;
// ll const inf = 1LL<<60;

typedef int Weight;
struct Edge {
    int src, dst;
    Weight weight;
    Edge(int src_, int dst_, Weight weight_) :
        src(src_), dst(dst_), weight(weight_) { }
};
bool operator < (const Edge &e, const Edge &f) {
    return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
        e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

pair<vector<int>,Edges> bridge(const Graph& g){
    const int n = g.size();
    int idx = 0, s = 0, t = 0, k = 0;
    vector<int> ord(n, -1), onS(n), stk(n), roots(n), cmp(n);
    Edges brdg;
    function<void(int,int)> dfs = [&](int v, int u){
        ord[v] = idx++;
        stk[s++] = v; onS[v] = true;
        roots[t++] = v;
        for(auto &e : g[v]){
            int w = e.dst;
            if(ord[w] == -1) dfs(w,v);
            else if(u != w && onS[w]) while(ord[roots[t-1]] > ord[w]) --t;
        }
        if(v == roots[t-1]){
            brdg.emplace_back(u,v,0);
            while(1){
                int w = stk[--s]; onS[w] = false;
                cmp[w] = k;
                if(v == w) break;
            }
            --t; ++k;
        }
    };
    for(int u = 0; u < n; u++){
        if(ord[u] == -1){ dfs(u,n); brdg.pop_back(); }
    }
    return make_pair(cmp,brdg);
}

/*
  セグメント木
  コンストラクタには要素数を渡す
  * 根 : 1
  * 左からx番目の葉 : x+N
  * iの親のindex : i/2
  * iの子のindex : i*2+0, i*2+1
  * iの兄弟(sibling) : i^1
  * iの深さ(depth) : log_2 iの整数部分
  * iの区間幅(width) : N/highest(i)
  * iの区間の左端 : (i-highest(i))*width(i)
  */

typedef ll dat_t;
dat_t const inf = (1LL<<31)-1;
dat_t const init = (1LL<<31)-1;
struct segment_tree {
    vector<pair<dat_t,int>> dat;
    int n;
    segment_tree(int n_){
        n = 1;
        while(n < n_) n<<=1;
        dat.resize(n*2);
        for(int i=n; i<n+n; i++){
            dat[i] = make_pair(init,i); // -infをdat[i]にするとvectorからのコンストラクタになる
        }
        for(int i=n-1; i>=1; i--){
            dat[i] = min(dat[i<<1], dat[i<<1|1]);
        }
    }
    // bottom-up
    void set(int k, dat_t x){
        int i = n+k; // leaf
        dat[i] = make_pair(x,k);
        while(i != 1){ // 1 is root
            dat[i>>1] = min(dat[i], dat[i^1]);
            i>>=1;
        }
    }
    // top-down
    pair<dat_t,int> get(int a, int b, int k, int l, int r){
        if(r <= a || b <= l) return make_pair(inf,0);
        if(a <= l && r <= b) return dat[k];
        pair<dat_t,int> v1 = get(a,b,k<<1,l,(l+r)/2);
        pair<dat_t,int> v2 = get(a,b,k<<1|1,(l+r)/2,r);
        return min(v1,v2);
    }
    pair<dat_t,int> get(int a, int b){
        return get(a,b,1,0,n);
    }
};

class LowestCommonAncestor {
public:
    int n;
    LowestCommonAncestor(int n_)
        : n(n_),
          g(n),
          ord(new int[n*2]),
          depth(new int[n*2]),
          id(new int[n]),
          rmq(new segment_tree(n*2)) {
    }
    void add_edge(int a, int b){
        g[a].eb(a,b,0);
    }
    void compile(int root = 0){
        int k = 0;
        dfs(root,-1,0,k);
        for(int i=0;i<k;i++){
            rmq->set(i,depth[i]);
        }
    }
    int lca(int u, int v){
        int a = id[u], b = id[v];
        return ord[rmq->get(min(a,b), max(a,b)+1).second];
    }
    Graph g;
private:
    unique_ptr<int[]> ord, depth, id;
    unique_ptr<segment_tree> rmq;
    void dfs(int v, int p, int d, int & k){
        id[v] = k;
        ord[k] = v; depth[k] = d;
        k++;
        for(auto & e : g[v]){
            if(e.dst != p){
                dfs(e.dst, v, d+1, k);
                ord[k] = v; depth[k] = d;
                k++;
            }
        }
    }
};
typedef LowestCommonAncestor LCA;

void dfs(int cur, int v, Graph const & g, vector<Weight> & res, vector<bool> & vis){
    res[v] = cur;
    vis[v] = true;
    for(auto & e : g[v]){
        if(vis[e.dst]) continue;
        dfs(cur+1, e.dst, g, res, vis);
    }
}

vector<Weight> dijkstra(Graph const & g, int s) {
    int n = g.size();
    vector<Weight> res(n);
    vector<bool> vis(n);
    dfs(0,s,g,res,vis);
    return res;
}

int d(int a, int b, int l, vector<Weight> & dist){
    return dist[a] - dist[l] + dist[b] - dist[l];
}

signed main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    int n,m;
    while(cin >> n >> m){
        Graph g(n);
        rep(i,m){
            int x,y;
            cin >> x >> y;
            x--;
            y--;
            g[x].eb(x,y,1);
            g[y].eb(y,x,1);
        }

        Edges brdg;
        vector<int> dic;
        tie(dic,brdg) = bridge(g);
        LCA lca(brdg.size()+1);
        for(auto &e : brdg){
            int a = dic[e.src], b = dic[e.dst];
            lca.add_edge(a,b);
            lca.add_edge(b,a);
        }
        lca.compile(0);
        vector<Weight> dist = dijkstra(lca.g,0);
        int q;
        cin >> q;
        rep(i,q){
            int a,b,c;
            cin >> a >> b >> c;
            a--;
            b--;
            c--;
            int A = dic[a], B = dic[b], C = dic[c];
            int lAB = lca.lca(A,B);
            int lBC = lca.lca(B,C);
            int lAC = lca.lca(A,C);
            bool ok = d(A,B,lAB,dist) + d(B,C,lBC,dist) == d(A,C,lAC,dist);
            cout << (ok ? "OK" : "NG") << '\n';
        }
    }
}

Submission Info

Submission Time
Task D - 旅行会社高橋君
User tubo28
Language C++11 (GCC 4.9.2)
Score 100
Code Size 7236 Byte
Status AC
Exec Time 512 ms
Memory 30180 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 100 / 100
Status
AC × 3
AC × 77
Set Name Test Cases
Sample sample_0.txt, sample_1.txt, sample_2.txt
All bigcycleandsub_0.txt, bigcycleandsub_1.txt, cluster_0.txt, cluster_1.txt, cluster_2.txt, cluster_3.txt, cluster_4.txt, cycleline_0.txt, cycleline_1.txt, cycleline_2.txt, cycleline_3.txt, cycleline_4.txt, cycletree_0.txt, cycletree_1.txt, cycletree_2.txt, cycletree_3.txt, cycletree_4.txt, large_0.txt, large_1.txt, large_2.txt, line_0.txt, line_1.txt, lineandsub_0.txt, lineandsub_1.txt, lineandsub_2.txt, maxrand_0.txt, maxrand_1.txt, maxrand_2.txt, maxrandandsub_0.txt, maxrandandsub_1.txt, maxrandandsub_2.txt, maxrandandsub_3.txt, maxrandandsub_4.txt, med_0.txt, med_1.txt, med_2.txt, med_3.txt, med_4.txt, med_5.txt, med_6.txt, med_7.txt, med_8.txt, med_9.txt, perfect_0.txt, perfect_1.txt, perfect_2.txt, small_0.txt, small_1.txt, small_2.txt, small_3.txt, small_4.txt, small_5.txt, small_6.txt, small_7.txt, small_8.txt, small_9.txt, star_0.txt, star_1.txt, star_2.txt, tencluster_0.txt, tencluster_1.txt, tencluster_2.txt, tencluster_3.txt, tencluster_4.txt, tree_0.txt, tree_1.txt, tree_2.txt, verysmall_0.txt, verysmall_1.txt, verysmall_2.txt, verysmall_3.txt, verysmall_4.txt, verysmall_5.txt, verysmall_6.txt, verysmall_7.txt, verysmall_8.txt, verysmall_9.txt
Case Name Status Exec Time Memory
bigcycleandsub_0.txt AC 294 ms 13544 KB
bigcycleandsub_1.txt AC 240 ms 13544 KB
cluster_0.txt AC 259 ms 12720 KB
cluster_1.txt AC 263 ms 12712 KB
cluster_2.txt AC 257 ms 12424 KB
cluster_3.txt AC 263 ms 12836 KB
cluster_4.txt AC 269 ms 12580 KB
cycleline_0.txt AC 290 ms 9376 KB
cycleline_1.txt AC 294 ms 9388 KB
cycleline_2.txt AC 299 ms 9252 KB
cycleline_3.txt AC 291 ms 9256 KB
cycleline_4.txt AC 289 ms 9388 KB
cycletree_0.txt AC 333 ms 9128 KB
cycletree_1.txt AC 329 ms 9248 KB
cycletree_2.txt AC 323 ms 9256 KB
cycletree_3.txt AC 329 ms 9128 KB
cycletree_4.txt AC 321 ms 9256 KB
large_0.txt AC 220 ms 16420 KB
large_1.txt AC 59 ms 3228 KB
large_2.txt AC 165 ms 14240 KB
line_0.txt AC 342 ms 30172 KB
line_1.txt AC 226 ms 30172 KB
lineandsub_0.txt AC 439 ms 30180 KB
lineandsub_1.txt AC 438 ms 30180 KB
lineandsub_2.txt AC 435 ms 30180 KB
maxrand_0.txt AC 243 ms 18736 KB
maxrand_1.txt AC 239 ms 18724 KB
maxrand_2.txt AC 235 ms 18724 KB
maxrandandsub_0.txt AC 315 ms 18412 KB
maxrandandsub_1.txt AC 316 ms 18404 KB
maxrandandsub_2.txt AC 325 ms 18436 KB
maxrandandsub_3.txt AC 359 ms 18400 KB
maxrandandsub_4.txt AC 321 ms 18404 KB
med_0.txt AC 29 ms 1104 KB
med_1.txt AC 27 ms 1052 KB
med_2.txt AC 28 ms 1064 KB
med_3.txt AC 28 ms 1052 KB
med_4.txt AC 29 ms 1180 KB
med_5.txt AC 28 ms 1068 KB
med_6.txt AC 28 ms 1172 KB
med_7.txt AC 28 ms 1068 KB
med_8.txt AC 27 ms 1040 KB
med_9.txt AC 28 ms 1068 KB
perfect_0.txt AC 81 ms 3496 KB
perfect_1.txt AC 60 ms 3740 KB
perfect_2.txt AC 80 ms 3500 KB
sample_0.txt AC 28 ms 1052 KB
sample_1.txt AC 28 ms 1056 KB
sample_2.txt AC 28 ms 1052 KB
small_0.txt AC 29 ms 924 KB
small_1.txt AC 31 ms 1056 KB
small_2.txt AC 29 ms 1040 KB
small_3.txt AC 29 ms 1052 KB
small_4.txt AC 29 ms 1052 KB
small_5.txt AC 29 ms 1044 KB
small_6.txt AC 28 ms 1060 KB
small_7.txt AC 28 ms 912 KB
small_8.txt AC 28 ms 1056 KB
small_9.txt AC 27 ms 936 KB
star_0.txt AC 431 ms 26312 KB
star_1.txt AC 440 ms 26308 KB
star_2.txt AC 448 ms 26312 KB
tencluster_0.txt AC 251 ms 13476 KB
tencluster_1.txt AC 256 ms 13224 KB
tencluster_2.txt AC 250 ms 13224 KB
tencluster_3.txt AC 247 ms 13536 KB
tencluster_4.txt AC 249 ms 13480 KB
tree_0.txt AC 511 ms 26204 KB
tree_1.txt AC 503 ms 26140 KB
tree_2.txt AC 512 ms 26208 KB
verysmall_0.txt AC 28 ms 972 KB
verysmall_1.txt AC 27 ms 1044 KB
verysmall_2.txt AC 27 ms 1044 KB
verysmall_3.txt AC 28 ms 1040 KB
verysmall_4.txt AC 28 ms 944 KB
verysmall_5.txt AC 26 ms 932 KB
verysmall_6.txt AC 26 ms 1012 KB
verysmall_7.txt AC 26 ms 928 KB
verysmall_8.txt AC 27 ms 980 KB
verysmall_9.txt AC 27 ms 1048 KB