Submission #354781

#TimeUsernameProblemLanguageResultExecution timeMemory
354781codebuster_10Valley (BOI19_valley)C++17
100 / 100
615 ms78556 KiB
#include <bits/stdc++.h>
 
using namespace std ;
 
#define i64 int64_t // typecast using i64(x)
#define int int64_t 
#define ld long double
#define f(i,a,b) for(int i=a; i<b; ++i)
#define endl '\n'
 
#define PQ priority_queue
#define LB lower_bound  
#define UB upper_bound
#define fr first
#define sc second
 
#define all(a) (a).begin(),(a).end()
#define allr(a) (a).rbegin(),(a).rend()
#define sz(x) ((int)(x).size())
 
//#ifndef ONLINE_JUDGE
template<typename T>
void __p(T a) {
  cout<<a; 
}
template<typename T, typename F>
void __p(pair<T, F> a) {
  cout<<"{";
  __p(a.first);
  cout<<",";
  __p(a.second);
  cout<<"}\n"; 
}
template<typename T>
void __p(std::vector<T> a) {
  cout<<"{";
  for(auto it=a.begin(); it<a.end(); it++)
    __p(*it),cout<<",}\n"[it+1==a.end()]; 
}
template<typename T, typename ...Arg>
void __p(T a1, Arg ...a) {
  __p(a1);
  __p(a...);
}
template<typename Arg1>
void __f(const char *name, Arg1 &&arg1) {
  cout<<name<<" : ";
  __p(arg1);
  cout<<endl;
}
template<typename Arg1, typename ... Args>
void __f(const char *names, Arg1 &&arg1, Args &&... args) {
  int bracket=0,i=0;
  for(;; i++)
    if(names[i]==','&&bracket==0)
      break;
    else if(names[i]=='(')
      bracket++;
    else if(names[i]==')')
      bracket--;
  const char *comma=names+i;
  cout.write(names,comma-names)<<" : ";
  __p(arg1);
  cout<<" | ";
  __f(comma+1,args...);
}
//#endif
 
void setIO(string s = "") {
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); 
  cin.exceptions(cin.failbit); 
  if(sz(s)){
    freopen((s+".in").c_str(),"r",stdin);
    freopen((s+".out").c_str(),"w",stdout);
  }
}
const int INF = 1e16 ;
/**
 * Description: Euler Tour, LCA,  kth_ancestor
 * source: own
  * The root points to itself.
  * 0 based indexing
 * Time: O(N\log N) build, O(log N) LCA
 * Source: cp-algorithm, own
 * Verification: to be done
  * for kth_ancestor : https://cses.fi/problemset/result/1573131/
  * for lca : https://cses.fi/problemset/result/1573158/
 */
struct LCA {
  int N, timer = 0, LOG ; 
  vector< vector<int> > up, dis, val ;
  vector< vector< array<int,2> > > adj ;
  vector<int> tin, tout, depth, C, vec ;
 
  void init(int _N) { 
    N = _N ; LOG = log2(N) + 5 ; 
    adj.resize(N) ; 
    up.resize(N, vector<int> (LOG)) ;
    dis.resize(N, vector<int> (LOG)) ;
    val.resize(N, vector<int> (LOG, INF)) ;
    tin = tout = depth = vector<int> (N) ; 
    vec = vector<int> (N,INF) ; 
  }
 
  void ae(int x, int y,int w) { // add edge
    adj[x].push_back({y,w}), adj[y].push_back({x,w}); 
  }
 
  void dfs(int v, int p,int w){
    tin[v] = ++timer;
    up[v][0] = p ; dis[v][0] = w ;
    for(int i = 1; i < LOG; i++){
      up[v][i] = up[up[v][i-1]][i-1] ;
      dis[v][i] = dis[v][i-1] + dis[up[v][i-1]][i-1] ;
    } 
    for(auto [u,_w]:adj[v]) if(u != p){
      depth[u] = depth[v] + 1 ; dfs(u,v,_w) ;
    }
    tout[v] = ++timer ;
  }
 
  void gen(int R = 0) { 
    depth[R] = 0 ;
    dfs(R,R,0); 
    dfs2(R,R) ;
    f(i,0,N){
      val[i][0] = min(vec[i],dis[i][0] + vec[up[i][0]]) ;
    }
    f(j,1,LOG){
      f(i,0,N){
        val[i][j] = min(val[i][j-1],dis[i][j-1] + val[up[i][j-1]][j-1]) ;
      }
    }
  }
 
  void getC(vector<int> _C){
    C = _C ;
    for(auto i:C){
      vec[i] = 0 ;
    }
  }
 
  void dfs2(int i,int p){
    for(auto [j,w]:adj[i]) if(j!=p) {
      dfs2(j,i) ; vec[i] = min(vec[i],w + vec[j]) ;
    }
  }
 
  bool is_ancestor(int u, int v){
    return tin[u] <= tin[v] && tout[u] >= tout[v];
  }
 
  int lca(int u, int v){
    if( is_ancestor(u,v) )  return u;
    if( is_ancestor(v,u) )  return v;
    for(int i=LOG-1;i>=0;--i) {
      if( !is_ancestor(up[u][i],v) ){
        u = up[u][i] ;
      } 
    }
    return up[u][0];
  }
 
  int dist(int u, int v) {
    return depth[u] + depth[v] - 2 * depth[lca(u,v)]; 
  }
 
  int query(int i,int k){
    if(k == 0) return vec[i] ;
    int cur = dis[i][0] , ans = vec[i] ; i = up[i][0] ; k--;
    for(int j = LOG - 1; j >= 0; --j){
      if( (int(1) << j) <= k ){
        ans = min(ans, cur + val[i][j]) ;
        cur += dis[i][j] ;
        k -= (int(1) << j) ; 
        i = up[i][j] ; 
      }
    }
    assert(k == 0) ;
    ans = min(ans,cur + vec[i]) ;
    return ans ;
  }
};
signed main(){
  setIO() ; 
  int N, S, Q, E; cin >> N >> S >> Q >> E ; --E;
  vector<array<int,2> > edges ;
  LCA tree ; tree.init(N) ;
  f(i,0,N-1){
    int A, B, W; cin >> A >> B >> W ; --A,--B;
    edges.push_back({A,B}) ; tree.ae(A,B,W) ;
  }
  vector<int> C(S) ;
  f(i,0,S){ cin >> C[i] ; --C[i] ;}
 
  tree.getC(C) ;
  tree.gen(E) ;
  while(Q--){
    int I, R; cin >> I >> R ; --I,--R;
    int temp = tree.lca(edges[I][0],edges[I][1]) ;
    temp = (temp == edges[I][0] ? edges[I][1] : edges[I][0]) ;
    if( tree.lca(temp,R) != temp ){
      cout << "escaped\n" ; continue ;
    }
    int K = tree.depth[R] - tree.depth[temp]  ;
    int ans = tree.query(R,K) ;
    if(ans >= INF){
      cout << "oo\n" ;
    }else{
      cout << ans << endl ;
    }
  } 
}

Compilation message (stderr)

valley.cpp: In function 'void setIO(std::string)':
valley.cpp:73:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
   73 |     freopen((s+".in").c_str(),"r",stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
valley.cpp:74:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
   74 |     freopen((s+".out").c_str(),"w",stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...