Problem:
D: Walking
問題
$1$ から $N$ の番号がつけられている $N$ 個の島がある.
それぞれの島は $N-1$ 個の橋によって、どの $2$ つの島も何本かの橋を渡って互いに移動することができる.
それぞれの橋には耐久度があり、入力が与えられた時点での $i$ 番目の橋の耐久度は $w_i$ である.
それぞれの島にはお宝が $1$ つずつ置いており、島に滞在しているときにお宝を拾うことができる.
現在島 $S$ にいるyebiくんは、島 $E$ にある博物館に全てのお宝を運びたい.
yebiくんは✝魔力✝を持っているので、島 $v$ に訪問するたびに、 $v$ から出る全ての橋の耐久度が $T$ 減少する.
橋の耐久度が $0$ 以下になったとき、橋は崩壊し、それ以降には渡ることができなくなる.
yebiくんは博物館に全てのお宝を届けることができるか？
ただし、yebiくんは力持ちなので同時にいくつでもお宝を持ち運ぶことができる.
制約
入力値は全て整数である
$2 \leq N \leq 10^5$
$1 \leq S, E \leq N$
$0 \leq T \leq 10^9$
$1 \leq w_i \leq 10^9$
$1 \leq a_i, b_i \leq N$
入力形式
入力は以下の形式で与えられる
$N\ T\ S\ E$
$a_1\ b_1\ w_1$
:
:
$a_{N-1}\ b_{N-1}\ w_{N-1}$
出力
博物館に全てのお宝を届けることができるなら "Yes"、そうでなければ "No" を出力せよ.
また、末尾に改行を出力せよ.
サンプル
サンプル入力 1
4 10 1 4
1 2 52
1 3 68
3 4 45
サンプル出力 1
Yes
サンプル入力 2
4 10 1 4
1 2 15
1 3 60
3 4 10
サンプル出力 2
No
サンプル入力 3
3 0 1 3
1 2 5
2 3 5
サンプル出力 3
Yes
yebiくんの魔力は貧弱すぎて、橋の耐久度を減らすことはできない.

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;
int n, t, s, e;
vector<pair<int, int>> adj[N];
bool visited[N];

bool dfs(int v, int p) {
    visited[v] = true;
    for (auto& edge : adj[v]) {
        int u = edge.first;
        int w = edge.second;
        if (u == p) continue;
        if (w <= t) return false;
        if (!visited[u]) {
            if (!dfs(u, v)) return false;
        }
    }
    return true;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> t >> s >> e;
    s--; e--;
    for (int i = 0; i < n - 1; i++) {
        int a, b, w;
        cin >> a >> b >> w;
        a--; b--;
        adj[a].push_back({b, w});
        adj[b].push_back({a, w});
    }
    if (dfs(s, -1)) cout << "Yes\n";
    else cout << "No\n";
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 9536
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define N 100010
#define pii pair <int, int>
int n, t, s, e;
vector <int> adj[N];
map <pii, int> M;
map <pii, int> mp;
int p[N];
bool vis[N];
void dfs(int u){
	vis[u] = 1;
	for (int i = 0; i < adj[u].size(); i++) {
		int v = adj[u][i];
		if (vis[v]) continue;
		p[v] = u;
		dfs(v);
	}
}

int main(){
	cin >> n >> t >> s >> e;
	for (int i = 1; i < n; i++){
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].push_back(v);
		adj[v].push_back(u);
		M[make_pair(u, v)] = w;
		M[make_pair(v, u)] = w; 
	}	
	dfs(s);
	int u = e;
	while (u != s) {
		mp[{p[u], u}] = 1;
		mp[{u, p[u]}] = 1;
		u = p[u];
	}
	bool flag = 0;
	for (map <pii, int>::iterator mi = M.begin(); mi != M.end(); mi++) {
		pii p = mi->first;
		int w = mi->second;
			if (w <= t) flag = 1;
	}
	if (flag) puts("No");
	else puts("Yes");
}
accuracy: 1
time_ms: 140
memory_kb: 27760
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define N 100010
#define pii pair <int, int>
int n, t, s, e;
vector <int> adj[N];
map <pii, int> M;
map <pii, int> mp;
int p[N];
bool vis[N];
long long sum;
void dfs(int u){
	vis[u] = 1;
	for (int i = 0; i < adj[u].size(); i++) {
		int v = adj[u][i];
		if (vis[v]) continue;
		p[v] = u;
		dfs(v);
	}
}

int main(){
	cin >> n >> t >> s >> e;
	for (int i = 1; i < n; i++){
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].push_back(v);
		adj[v].push_back(u);
		M[make_pair(u, v)] = w;
		M[make_pair(v, u)] = w; 
	}	
	dfs(s);
	int u = e;
	while (u != s) {
		mp[{u, p[u]}] = 1;
		u = p[u];
	}
	bool flag = 0;
	for (map <pii, int>::iterator mi = M.begin(); mi != M.end(); mi++) {
		pii p = mi->first;
		int w = mi->second;
		if (!mp.count(p)) {
			if (w <= t) flag = 1;
		}
	}
	if (flag) puts("No");
	else puts("Yes");
}
accuracy: 1
time_ms: 130
memory_kb: 25560
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct Edge {
    int to;
    int weight;
    Edge(int to, int weight) : to(to), weight(weight) {}
};

int N, T, S, E;
vector<Edge> adj[100001];
bool visited[100001];

bool bfs() {
    queue<int> q;
    q.push(S);
    visited[S] = true;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (const Edge& e : adj[u]) {
            if (visited[e.to]) continue;
            if (e.weight <= T) return false;
            visited[e.to] = true;
            q.push(e.to);
        }
    }
    return true;
}

int main() {
    cin >> N >> T >> S >> E;
    S--;
    E--;
    for (int i = 0; i < N - 1; i++) {
        int a, b, w;
        cin >> a >> b >> w;
        a--;
        b--;
        adj[a].push_back(Edge(b, w));
        adj[b].push_back(Edge(a, w));
    }
    if (bfs()) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 9520
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    int n, s, e;
    long long t;
    cin >> n >> t >> s >> e;
    s--; e--;
    vector graph(n, vector<pair<int, int>>());
    for (int i = 0; i < n - 1; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        a--; b--;
        graph[a].emplace_back(b, c);
        graph[b].emplace_back(a, c);
    }
    if (t == 0) {
        cout << "Yes" << '\n';
        return 0;
    }
    vector<int> child(n);
    for (int i = 0; i < n; i++) {
        child[i] = graph[i].size() - (i == s ? 0 : 1);
    } 
    vector<bool> is_e_ancester(n, false);
    auto get_e_ancester = [&](auto self, int u, int p) -> bool {
        if (u == e) return is_e_ancester[u] = true;
        for (const auto& [v, w]: graph[u]) {
            if (v == p) continue;
            if (self(self, v, u)) return is_e_ancester[u] = true;
        }
        return false;
    };
    get_e_ancester(get_e_ancester, s, -1);

    auto dfs = [&](auto self, int u, int p) -> bool {
        bool is_root = (u == s);
        bool is_ok = true;
        pair<int, int> nxt;
        vector<int> children;
        for (const auto& [v, w]: graph[u]) {
            if (v == p) continue;
            if (is_e_ancester[v]) {
                nxt = {v, w};
                continue;
            }
            children.emplace_back((w - t * child[v] - 1) / t);
            is_ok &= self(self, v, u);
        }
        sort(children.begin(), children.end());
        for (int i = 0; i < (int)children.size(); i++) {
            is_ok &= (children[i] > i + !is_root);
        }
        if (is_ok) {
            if (!is_e_ancester[u]) return true;
            else if (u == e) return true;
            else if ((nxt.second + t - 1) / t > children.size() + !is_root) return self(self, nxt.first, u);
        }
        return false;
    };

    if (dfs(dfs, s, -1)) {
        cout << "Yes" << '\n';
    } else {
        cout << "No" << '\n';
    }
}
accuracy: 1
time_ms: 60
memory_kb: 18444
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i = 0; i<(n); i++)

using namespace std;
using ll = long long;
using P = pair<int,int>;
const int mod = 998244353;
const int inf = (1<<30);
const int dy[4] = {-1,0,0,1};
const int dx[4] = {0,-1,1,0};

const int mn = 100005*2;
#define int long long

vector<vector<P>> g(mn);//first 行き先 second cost;
vector<int> r(mn,0);
vector<int> ved(mn,0);
int s;
bool dfs1(int i){
    //cout<<i<<endl;
    ved[i] = true;
    if(i == s){
        r[s] = true;
        return true;
    }
    bool res = 0;
    for( P next : g[i]){
        if(ved[next.first] == true) continue;
        if(dfs1(next.first)) return r[i] = true;
    }
    return false;
}
ll t;
vector<int> vi(mn,0);
bool dfs2(int i){
    vector<ll> cost;
    int p = (s != i);
    vi[i] = true;
    //cout<<"!!"<<i<<endl;

    for(auto x : g[i]){
        if(vi[x.first]) continue;
        if(!dfs2(x.first)) return false;
       // cout<<"$$"<<endl;
        if(r[x.first] == 1){
          //  cout<<x.first<<endl;
            //if(!dfs2(x.first))return false;
            if( x.second - t*((int)(g[x.first].size())-1) <= 0) return false;
        }
        cost.push_back(x.second - t * (int)(g[x.first].size()) );
        //cout<<x.first<<" "<<(x.second - t * int(g[x.first].size()) )<<endl;;
    }
    sort(cost.begin(),cost.end());
    //cout<<"?? "<<i<<endl;
    for(int x : cost){
        if(x - p*t <= 0) return false;
        p++;
    }
    //cout<<"** "<<i<<endl;
    return true;
}


signed main(){
    int n,e;
    cin>>n>>t>>s>>e;
    s--;e--;
    rep(i,n-1){
        int a,b,c;
        cin>>a>>b>>c;
        a--;b--;
        g[a].push_back({b,c});
        g[b].push_back({a,c});
    }
       

    dfs1(e);
    //rep(i,n){
    //    cout<<r[i]<<" ";
    //}


    cout<<(dfs2(e) ? "Yes" : "No")<<endl;

    



}
accuracy: 1
time_ms: 60
memory_kb: 24080
final_rank: 9

code_snippet: #include<bits/stdc++.h>

using namespace std;

bool func(){
  int n;
  cin >> n;
  int t;
  cin >> t;
  int s;
  int e;
  cin >> s >> e;
  --s;
  --e;
  if(t == 0)return true;
  using P = pair<int,int>;
  vector<vector<P>> edges(n);
  for(int i=0;i<n-1;++i){
    int a;
    int b;
    int c;
    cin >> a >> b >> c;
    --a;
    --b;
    c = (c + t - 1) / t;
    edges[a].emplace_back(b,c);
    edges[b].emplace_back(a,c);
  }
  vector<vector<P>> childs(n);
  vector<int> parents(n,-1);
  {
    stack<int> st;
    vector<int> used(n,false);
    st.push(e);
    used[e] = true;
    while(st.size()){
      int p = st.top();
      st.pop();
      for(auto e:edges[p]){
        if(used[e.first])continue;
        used[e.first] = true;
        childs[p].emplace_back(e);
        parents[e.first] = p;
        st.push(e.first);
      }
    }
  }

  vector<int> dp(n,-1);
  function<bool(int)> has_goal = [&](int p) -> bool {
    if(p == e)return true;
    auto &it = dp[p];
    if(it >= 0)return it;
    it = false;
    for(auto e:edges[p]){
      if(has_goal(e.first)){
        it = true;
        break;
      }
    }
    return it;
  };

  function<int(int)> rec = [&](int p) -> int {
    int has_return = -1;
    vector<int> line;
    for(auto e:childs[p]){
      if(has_goal(e.first)){
        has_return = e.second - 1;
        if(rec(e.first) < 0)return -1;
      }else{
        int res = rec(e.first);
        if(res < 0){
          return -1;
        }
        line.push_back(e.second-1-res);
      }
    }
    sort(line.begin(),line.end());
    for(int i=0;i<line.size();++i){
      if(i + 2 > line[i]){
        return -1;
      }
    }
    if(has_return >= 0){
      if(has_return <= line.size()){
        return -1;
      }
    }
    return childs[p].size();
  };
  return rec(e) >= 0;
}

int main(){
  cout << (func() ? "Yes" : "No") << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 24360
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <queue>
using namespace std;

#define MAX 100005
#define rep(i,n) for(int i = 0; i < (n); i++)

typedef pair<int,int> pii;
map<pii,int> ma;

bool path[MAX];
vector<vector<int> > G;
int n, t, s, g;

int get(int a,int b){
    if(a == -1 || b == -1)return -1;
    if(a > b)swap(a,b);
    return ma[pii(a,b)];
}

void dec(int a, int b, int cnt){
    if(a == -1 || b == -1)return;
    if(a > b)swap(a,b);
    ma[pii(a,b)] -= cnt*t;
    return;
}

void dfs_path(int now, int par){
    if(now == g)path[now] = true;
    for(auto ne: G[now]){
        if(ne == par)continue;
        dfs_path(ne,now);
        dec(now,ne,1);
        if(path[ne]){
            path[now] = true;
        }
    }
}

int dfs(int now, int par){
    int ret = 0;
    priority_queue<pii> q;
    for(auto ne: G[now]){
        if(path[ne] || ne == par)continue;//s-gパス上にある頂点には行かない
        int tmp = dfs(ne,now);
        dec(now,ne,tmp);
        ret++;
        q.push(pii(get(now,ne),ne));
    }
    while(q.size()){
        int v = q.top().second;
        dec(now,v,q.size());
        q.pop();
    }
    return ret;
}

int main(){
    cin >> n >> t >> s >> g;
    s--,g--;
    G = vector<vector<int> > (n);
    rep(i,n-1){
        int a,b,c;
        cin >> a >> b >> c;
        a--,b--;
        G[a].push_back(b);
        G[b].push_back(a);
        if(a > b) swap(a,b);
        ma[pii(a,b)] = c;
    }
    rep(i,G[s].size())dec(s,G[s][i],-1);
    dfs_path(s,-1);
    rep(i,n)if(path[i])dfs(i,-1);
    for(auto x: ma){
        //cout << x.first.first << " " << x.first.second << " " << x.second << endl;
        if(x.second <= 0){
            cout << "No" << endl;
            return 0;
        }
    }
    cout << "Yes" << endl;
}
accuracy: 1
time_ms: 170
memory_kb: 19312
final_rank: 10

code_snippet: /*  -*- coding: utf-8 -*-
 *
 * 3103.cc: Walking
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 100000;

/* typedef */

typedef long long ll;
typedef queue<int> qi;

struct Edge {
  int w, i, j;
  Edge() {}
  Edge(int _w, int _i, int _j): w(_w), i(_i), j(_j) {}

  int &src() { return i; }
  int &dst() { return j; }
  Edge reverse() { return Edge(w, j, i); }

  bool operator<(const Edge &e) const { return w < e.w; }

  bool magic_ok(int t, int vts[]) {
    ll mg = (ll)t * (vts[i] + vts[j]);
    //printf("(%d(%d)+%d(%d))*%d=%lld <=> %d\n",
    //vts[i], i, vts[j], j, t, mg, w);
    return (mg < w);
  }
};

typedef vector<Edge> ve;

/* global variables */

ve nbrs[MAX_N];
int ps[MAX_N], cis[MAX_N], vts[MAX_N];
Edge pes[MAX_N], ses[MAX_N];
bool sps[MAX_N];

/* subroutines */

/* main */

int main() {
  int n, t, st, gl;
  scanf("%d%d%d%d", &n, &t, &st, &gl);
  st--, gl--;

  for (int i = 1; i < n; i++) {
    int a, b, w;
    scanf("%d%d%d", &a, &b, &w);
    a--, b--;
    nbrs[a].push_back(Edge(w, a, b));
    nbrs[b].push_back(Edge(w, b, a));
  }

  for (int i = 0; i < n; i++)
    sort(nbrs[i].begin(), nbrs[i].end());

  ps[st] = -1;
  qi q;
  q.push(st);

  while (! q.empty()) {
    int u = q.front(); q.pop();
    int &up = ps[u];
    ve &nbru = nbrs[u];
    for (ve::iterator vit = nbru.begin(); vit != nbru.end(); vit++) {
      Edge &e = *vit;
      int &v = e.dst();
      if (v != up) {
	ps[v] = u;
	pes[v] = e.reverse();
	q.push(v);
      }
    }
  }

  for (int u = gl; u >= 0; u = ps[u]) sps[u] = true;
  
  for (int u = st; u >= 0;) {
    int &up = ps[u], &ciu = cis[u];
    ve &nbru = nbrs[u];

    while (ciu < nbru.size()) {
      int &v = nbru[ciu].dst();
      if (up == v) ciu++;
      else if (sps[v]) {
	ses[u] = nbru[ciu];
	//printf("ses[%d]=Edge(%d,%d,%d)\n", u, ses[u].w, ses[u].i, ses[u].j);
	ciu++;
      }
      else break;
    }

    if (ciu >= nbru.size()) {
      if (ses[u].w > 0) {
	if (! ses[u].magic_ok(t, vts)) {
	  puts("No");
	  return 0;
	}
	ses[u].w = 0;
	u = ses[u].dst();
	vts[u]++;
      }
      else if (u == gl) {
	u = -1;
      }
      else {
	if (up >= 0) {
	  if (! pes[u].magic_ok(t, vts)) {
	    puts("No");
	    return 0;
	  }
	  vts[up]++;
	}
	u = up;
      }
    }
    else {
      if (! nbru[ciu].magic_ok(t, vts)) {
	puts("No");
	return 0;
      }
      u = nbru[ciu++].dst();
      vts[u]++;
    }
  }

  puts("Yes");
  return 0;
}
accuracy: 0.9714285714285714
time_ms: 50
memory_kb: 11476
final_rank: 17

code_snippet: //
// Created by yamunaku on 2019/10/06.
//

#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define repl(i, l, r) for(int i = (l); i < (r); i++)
#define per(i, n) for(int i = ((n)-1); i >= 0; i--)
#define perl(i, l, r) for(int i = ((r)-1); i >= (l); i--)
#define all(x) (x).begin(),(x).end()
#define MOD9 998244353
#define MOD1 1000000007
#define IINF 1000000000
#define LINF 1000000000000000000
#define SP <<" "<<
#define CYES cout<<"Yes"<<endl
#define CNO cout<<"No"<<endl
#define CFS cin.tie(0);ios::sync_with_stdio(false)
#define CST(x) cout<<fixed<<setprecision(x)

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<vector<int>> mti;
typedef vector<ll> vl;
typedef vector<vector<ll>> mtl;

ll t;
int start, goal;

struct edge{
    int to;
    int id;
};

vector<vector<edge>> e;
vl w;

bool dfs(int x, int p){
    int sz = e[x].size();
    rep(i, sz){
        if(e[x][i].to != p){
            if(dfs(e[x][i].to, x)){
                auto tmp = e[x][i];
                repl(j, i, sz - 1){
                    e[x][j] = e[x][j + 1];
                }
                e[x][sz - 1] = tmp;
                return true;
            }
        }
    }
    return x == goal;
}

int dfs2(int x, int p){
    int sz = e[x].size();
    rep(i, sz){
        w[e[x][i].id] -= t;
    }
    bool ok = false;
    rep(i, sz){
        if(e[x][i].id != p){
            if(w[e[x][i].id] > 0){
                int ret = dfs2(e[x][i].to, e[x][i].id);
                if(ret == 1) return 1;
                if(ret == 2) ok = true;
            }else{
                return 1;
            }
            rep(j, sz){
                w[e[x][j].id] -= t;
            }
        }
    }
    if(x == goal) ok = true;
    if(ok){
        return 2;
    }else{
        if(w[p] > 0) return 0;
        else return 1;
    }
}


int main(){
    int n;
    cin >> n >> t;
    cin >> start >> goal;
    start--, goal--;
    int u, v, ww;
    e = vector<vector<edge>>(n);
    w = vl(n);
    rep(i, n - 1){
        cin >> u >> v >> ww;
        u--, v--;
        e[u].push_back({v, i});
        e[v].push_back({u, i});
        w[i] = ww;
    }
    rep(i, n){
        sort(all(e[i]), [&](const edge &l, const edge &r){
            return w[l.id] < w[r.id];
        });
    }
    dfs(start, -1);
    int sz = e[start].size();
    rep(i, sz){
        w[e[start][i].id] += t;
    }
    if(dfs2(start, -1) == 2) CYES;
    else
        CNO;
    return 0;
}
accuracy: 0.9714285714285714
time_ms: 80
memory_kb: 13264
final_rank: 18

code_snippet: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;
using ll = long long int;
using int64 = long long int;
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1001001001;
const ll LONGINF = 1001001001001001LL;
const ll MOD = 1000000007LL;
 
int main() {
    ll N, T, S, E; cin >> N >> T >> S >> E; S--; E--;
    vector< vector<int> > G(N);
    map< pair<int, int>, ll > pr;
    for(int i=0; i+1<N; i++) {
        int u, v, w; cin >> u >> v >> w;
        u--; v--;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
        if(u > v) swap(u, v);
        pr[make_pair(u, v)] = w;
    }

    vector<ll> lim(N), anc(N), cnt(N);
    function<void(int, int)> dfs = [&](int cur, int par) {
        if(cur == E) anc[cur] = true;
        for(auto to : G[cur]) {
            if(to == par) continue;
            dfs(to, cur);
            anc[cur] |= anc[to];
        }
    };

    function<bool(int, int)> solve = [&](int cur, int par) {
        vector<int> ch;
        for(auto to : G[cur]) if(to != par) ch.emplace_back(to);
        sort(ch.begin(), ch.end(), [&](int x, int y) {
                if(anc[x]) return false;
                if(anc[y]) return true;

                pair<int, int> px = minmax({cur, x});
                pair<int, int> py = minmax({cur, y});
                ll tx = pr[px] - 1LL * T * (G[x].size() - 1);
                ll ty = pr[py] - 1LL * T * (G[y].size() - 1);
                return tx < ty;
            });

        bool res = true;
        for(auto to : ch) {
            pair<int, int> p = minmax({cur, to});
            ll hp1 = pr[p] - 1LL * T * (cnt[cur] + cnt[to]);
            // fprintf(stderr, "cur = %d, to = %d, hp1 = %lld\n", cur + 1, to + 1, hp1);
            if(hp1 <= 0) return false;
            cnt[to]++;
            res &= solve(to, cur);

            if(anc[to]) continue;
            ll hp2 = pr[p] - 1LL * T * (cnt[cur] + cnt[to]);
            // fprintf(stderr, "cur = %d, to = %d, hp2 = %lld\n", cur + 1, to + 1, hp2);
            if(hp2 <= 0) return false;
            cnt[cur]++;
        }
        return res;
    };

    dfs(S, -1);
    bool ans = solve(S, -1);
    cout << (ans ? "Yes" : "No") << endl;
    return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 22076
final_rank: 16

code_snippet: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;
using ll = long long int;
using int64 = long long int;
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1001001001;
const ll LONGINF = 1001001001001001LL;
const ll MOD = 1000000007LL;
 
int main() {
    ll N, T, S, E; cin >> N >> T >> S >> E; S--; E--;
    vector< vector<int> > G(N);
    map< pair<int, int>, ll > pr;
    for(int i=0; i+1<N; i++) {
        int u, v, w; cin >> u >> v >> w;
        u--; v--;
        G[u].emplace_back(v);
        G[v].emplace_back(u);
        if(u > v) swap(u, v);
        pr[make_pair(u, v)] = w;
    }

    vector<ll> lim(N), anc(N), cnt(N);
    function<void(int, int)> dfs = [&](int cur, int par) {
        if(cur == E) anc[cur] = true;
        for(auto to : G[cur]) {
            if(to == par) continue;
            dfs(to, cur);
            anc[cur] |= anc[to];
        }
    };

    function<bool(int, int)> solve = [&](int cur, int par) {
        vector<int> ch;
        for(auto to : G[cur]) if(to != par) ch.emplace_back(to);
        sort(ch.begin(), ch.end(), [&](int x, int y) {
                if(anc[x]) return false;
                if(anc[y]) return true;

                pair<int, int> px = minmax({cur, x});
                pair<int, int> py = minmax({cur, y});
                ll tx = pr[px] - 1LL * T * (G[x].size() - 1);
                ll ty = pr[py] - 1LL * T * (G[y].size() - 1) - T;
                return tx < ty;
            });

        bool res = true;
        for(auto to : ch) {
            pair<int, int> p = minmax({cur, to});
            ll hp1 = pr[p] - 1LL * T * (cnt[cur] + cnt[to]);
            // fprintf(stderr, "cur = %d, to = %d, hp1 = %lld\n", cur + 1, to + 1, hp1);
            if(hp1 <= 0) return false;
            cnt[to]++;
            res &= solve(to, cur);

            if(anc[to]) continue;
            ll hp2 = pr[p] - 1LL * T * (cnt[cur] + cnt[to]);
            // fprintf(stderr, "cur = %d, to = %d, hp2 = %lld\n", cur + 1, to + 1, hp2);
            if(hp2 <= 0) return false;
            cnt[cur]++;
        }
        return res;
    };

    dfs(S, -1);
    bool ans = solve(S, -1);
    cout << (ans ? "Yes" : "No") << endl;
    return 0;
}
accuracy: 0.9714285714285714
time_ms: 370
memory_kb: 22028
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;

typedef pair<int,int>P;
#define F first
#define S second

int n,T,s,t;
vector<P>v[100009];
int E_aru[100009];


void END(){
  cout<<"No"<<endl;
  exit(0);
}

void YEAY(){
  cout<<"Yes"<<endl;
  exit(0);
}



int dfs0(int x,int par);
int dfs(int x,int par){

  int ofset = -T;
  int p_cost=-1;
  if(x==s)ofset=0;

  vector<P>vec;
  r(i,v[x].size()){
    if(E_aru[x] == v[x][i].F)continue;
    if(v[x][i].F == par){
      p_cost = i;
      v[x][p_cost].S -= T;
      continue;
    }
    vec.push_back( P(v[x][i].S,i) );
  }

  sort(vec.begin(),vec.end());

  r(i,vec.size()){

    if(v[x][vec[i].S].S + ofset <=0 )END();
    dfs( v[x][vec[i].S].F , x );

    if(p_cost != -1)v[x][p_cost].S -= T;
    ofset -= T;
  }

  if(E_aru[x] != -1){
    r(i,v[x].size()){
      if(E_aru[x] != v[x][i].F)continue;
      if(v[x][i].S +  ofset <=0 )END();
      dfs( E_aru[x] , x );
    }
  }

  if(x==t)YEAY();

  if(p_cost != -1 &&  v[x][p_cost].S <= 0)END();
}


signed main(){
  memset(E_aru,-1,sizeof(E_aru));
  cin>>n;
  cin>>T>>s>>t; s--; t--;

  r(i,n-1){
    int a,b,c;
    cin>>a>>b>>c; a--; b--;
    v[a].push_back(P(b,c));
    v[b].push_back(P(a,c));
  }

  dfs0(s,-1);
  dfs(s,-1);

  cout<<"DAME"<<endl;
  exit(1);
}





int dfs0(int x,int par){
  if(x==t)return 1;
  int res=0;
  r(i,v[x].size()){
    if(v[x][i].F==par)continue;
    int X=dfs0(v[x][i].F,x);
    if(X==1)E_aru[x] = v[x][i].F , res=1;
  }
  return res;
}
accuracy: 1
time_ms: 70
memory_kb: 12364
final_rank: 3

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 100005



int N,start,goal;
int PARENT[SIZE];
ll T,num_visited[SIZE];

struct Edge{
	Edge(int arg_to,ll arg_weight){
		to = arg_to;
		weight = arg_weight;
		value = -1;
	}
	bool operator<(const struct Edge &arg) const{

		return value < arg.value;
	}

	int to;
	ll weight,value;
};

vector<Edge> G[SIZE];


void dfs(int node_id,int parent){

	PARENT[node_id] = parent;

	bool FLG = false;
	int edge_index;

	vector<Edge> V;

	for(int i = 0; i < G[node_id].size(); i++){

		int child = G[node_id][i].to;
		if(child == parent || child == goal)continue;

		num_visited[child]++;
		dfs(child,node_id);
		G[node_id][i].value = G[node_id][i].weight-num_visited[child]*T;
	}
	sort(G[node_id].begin(),G[node_id].end());

	for(int i = 0; i < G[node_id].size(); i++){

		int child = G[node_id][i].to;
		if(child == parent)continue;

		if(child == goal){

			FLG = true;
			edge_index = i;
			continue;
		}

		G[node_id][i].weight -= (num_visited[node_id]+num_visited[child])*T;
		num_visited[node_id]++;
	}

	if(FLG){ //ゴールは最後に訪れる

		num_visited[goal]++;
		dfs(goal,node_id);
		G[node_id][edge_index].weight -= T*(num_visited[node_id]+num_visited[goal]);
	}
}

int main(){

	scanf("%d %lld %d %d",&N,&T,&start,&goal);
	start--;
	goal--;

	int from,to;
	ll weight;

	for(int loop = 0; loop < N-1; loop++){

		scanf("%d %d %lld",&from,&to,&weight);

		from--;
		to--;

		G[from].push_back(Edge(to,weight));
		G[to].push_back(Edge(from,weight));
	}

	for(int i = 0; i < N; i++){

		num_visited[i] = 0;
	}

	dfs(start,-1);

	//戻りのコストの過剰計上分を直す(戻りはgoalで止まるので、片道分のコストがあれば良い)
	int tmp_node = goal;

	while(true){

		int parent = PARENT[tmp_node];

		if(parent == -1)break;

		for(int i = 0; i < G[parent].size();i++){

			if(G[parent][i].to == tmp_node){

				G[parent][i].weight += num_visited[tmp_node]*T;
				break;
			}
		}

		if(parent == start)break;
		tmp_node = parent;
	}

	for(int i = 0; i < N; i++){
		for(int k = 0; k < G[i].size(); k++){
			if(G[i][k].weight <= 0){

				printf("No\n");
				return 0;
			}
		}
	}

	printf("Yes\n");

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 18036
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
using namespace std;
#define int long long
int MOD = 1000000007;
vector<vector<int> > g;
vector<vector<int> > c;
int N, T, S, E;
vector<int>A;
bool found = false;
void dfs1(int a, int p = -1) {
	if (a == S) {
		found = true;
		return;
	}
	for (int i = 0; i < g[a].size(); i++) {
		if (p != g[a][i]) {
			A[a] = g[a][i];
			dfs1(g[a][i], a);
			if (found) {
				break;
			}
		}
	}

}

bool start = false;
bool ok = true;
void dfs2(int a, int p, int C) {
	//cerr << a + 1 << " " << C << endl;
	int times = 0;
	if (!start && a == S) {
		start = true;
	}
	else if(start){
		
		times++;
	}
	vector<pair<int, int> > vp;
	for (int i = 0; i < g[a].size(); i++) {
		if (p != g[a][i]) {
			vp.emplace_back(c[a][i] - T * (g[g[a][i]].size()), i);
		}
	}
	if (!start) {
		for (int i = 0; i < vp.size(); i++) {
			if (g[a][vp[i].second] == A[a]) {
				swap(vp[i], vp.back());
				vp.pop_back();
			}
		}


		for (int i = 0; i < g[a].size(); i++) {
			if(g[a][i] == A[a]){
				dfs2(A[a], a, c[a][i]);
			}
		}
		times++;
	}
	
	sort(vp.begin(), vp.end());
	for (int ii = 0; ii < vp.size(); ii++) {
		int i = vp[ii].second;
		dfs2(g[a][i], a, c[a][i] - T * times);
		times++;
	}
	if (C - T * times <= 0) {
		//cerr << a + 1 << " " << times << endl;
		ok = false;
	}
}


signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	cin >> N >> T >> S >> E;
	S--; E--;
	g.resize(N);
	c.resize(N);
	A.resize(N, -1);
	int res = 0;
	int a, b, cost;
	for (int i = 0; i < N - 1; i++) {
		cin >> a >> b >> cost; a--; b--;
		g[a].push_back(b);
		c[a].push_back(cost);
		g[b].push_back(a);
		c[b].push_back(cost);
	}
	dfs1(E);

	int INF = (int)1 << 60;
	dfs2(E, -1, INF);
	if (ok) {
		cout << "Yes" << endl;
	}
	else {
		cout << "No" << endl;
	}
}
accuracy: 1
time_ms: 70
memory_kb: 26548
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define ll long long

//#define TEST

struct edge {
	int from = 0, to = 0; ll weight = 0;
	int cnt = 0;
	ll evl = 0; // 評価値
	edge() {}
	edge(int f, int t, ll w) {
		from = f;
		to = t;
		weight = w;
	}
};

int n, s, e;
ll t;
vector<vector<edge*>> g; // 隣接リスト
edge es[100000];
vector<int> parent;

void dfs(int s) { // parentを構築する
	for (auto eg : g[s]) {
		if (eg->from == s && parent[eg->to] == -1) {
			parent[eg->to] = s;
			dfs(eg->to);
		}
		else if (eg->to == s && parent[eg->from] == -1) {
			parent[eg->from] = s;
			dfs(eg->from);
		}
	}
}

void visit(int i) {
	for (auto eg : g[i]) {
		eg->weight -= t;
	}
}

int got = 1;
vector<int> visited;
void solve(int s) {
	for (auto eg : g[s]) {
		int to;
		if (eg->from == s)
			to = eg->to;
		else
			to = eg->from;
		if (visited[to])
			continue;
		if (eg->weight <= 0) {
			cout << "No" << endl;
			exit(0);
		}
		visit(to);
		visited[to] = 1;
		++got;
		solve(to);
		if (eg->weight <= 0) {
			cout << "No" << endl;
			exit(0);
		}
		visit(s);
	}
	if (got == n && s == e) {
		cout << "Yes" << endl;
		exit(0);
	}
}

signed main() {
	cin >> n >> t >> s >> e;
	--s; --e;

	g.resize(n);
	parent.resize(n, -1);

	for (int i = 0; i < n - 1; ++i) {
		int a, b; ll w;
		cin >> a >> b >> w;
		--a; --b;
		edge eg(a, b, w);
		es[i] = eg;
		g[a].push_back(es + i);
		g[b].push_back(es + i);
	}

#ifdef TEST
	cout << "------------es------------" << endl;
	for (int i = 0; i < n - 1; ++i) {
		auto eg = es[i];
		cout << (eg.from) << " " << (eg.to) << " " << (eg.weight) << endl;
	}
#endif

	parent[s] = s;
	dfs(s);

#ifdef TEST
	cout << "----------parent----------" << endl;
	for (auto pi : parent)
		cout << pi << " ";
	cout << endl;
#endif

	vector<int> cnt(n, 1); // 頂点iを何回訪れるか
	cnt[s] -= 2;
	for (auto pi : parent)
		cnt[pi]++;
	int now = e; int prt = parent[e];
	while (now != prt) {
		cnt[prt]--;
		now = prt;
		prt = parent[now];
	}

#ifdef TEST
	cout << "------------cnt-----------" << endl;
	for (auto ci : cnt)
		cout << ci << " ";
	cout << endl;
#endif

	for (int i = 0; i < n - 1; ++i) {
		es[i].cnt = cnt[es[i].from] + cnt[es[i].to];
		es[i].evl = es[i].weight - t * es[i].cnt;
	}

	now = e; prt = parent[e];
	while (now != prt) {
		for (auto eg : g[now]) {
			if ((*eg).from == now && (*eg).to == prt) {
				(*eg).evl = INT_MAX;
				break;
			}
			else if ((*eg).from == prt && (*eg).to == now) {
				(*eg).evl = INT_MAX;
				break;
			}
		}
		now = prt;
		prt = parent[now];
	}

#ifdef TEST
	cout << "-----------edge-----------" << endl;
	for (int i = 0; i < n - 1; ++i) {
		auto eg = es[i];
		cout << (eg.from) << " " << (eg.to) << " " << (eg.evl) << endl;
	}
#endif

	for (int i = 0; i < n; ++i) {
		sort(
			g[i].begin(),
			g[i].end(),
			[](const edge* e1, const edge* e2) {return (e1->evl < e2->evl); }
		);
	}

#ifdef TEST
	cout << "----------edge(sorted)-----" << endl;
	for (int i = 0; i < n; ++i) {
		cout << "i=" << i << endl;
		for (auto eg : g[i])
			cout << (eg->from) << " " << (eg->to) << " " << (eg->evl) << endl;
	}
#endif

	visited.resize(n, 0);
	visited[s] = 1;

	solve(s);

	return 0;
	}
accuracy: 1
time_ms: 90
memory_kb: 14420
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
#define prArr(a) {cerr<<(#a)<<"={";int i=0;for(auto t:(a))cerr<<(i++?", ":"")<<t;cerr<<"}"<<endl;}
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL<<60)+1e9; // ~ 1.15 * 1e18
const Int mod = (1e9)+7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int,Int>;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T1, class T2> ostream& operator<<(ostream& o,pair<T1,T2> p){return o<<"("<<p.first<<","<<p.second<<")";}
template<class T1, class T2, class T3> ostream& operator<<(ostream& o,tuple<T1,T2,T3> t){
  return o<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class T1, class T2> istream& operator>>(istream& i,pair<T1,T2> &p){return i>>p.first>>p.second;}
template<class T> ostream& operator<<(ostream& o,vector<T> a){Int i=0;for(T t:a)o<<(i++?" ":"")<<t;return o;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(T &t:a)i>>t;return i;}
//INSERT ABOVE HERE
class TreeParent{
public:
  Int V;                        //ノード数
  Int root;                     //根
  vector<vector<Int> > G;       //Graph
  vector<Int> parent;           //親
  Int ok;
  TreeParent():V(-1){};
  TreeParent(Int V,Int root = 0):V(V),root(root),G(V),parent(V),ok(0){}
  TreeParent(vector<vector<Int> > G,Int root = 0):V(G.size()),root(root),G(G),parent(V),ok(0){}
  void resize(Int n){*this = TreeParent(n);}
  void add_edge(Int a,Int b){
    ok = false;
    assert(a < V && b < V);
    assert(a >= 0 && b >= 0);
    G[a].push_back(b);
    G[b].push_back(a);
  }
  void build(Int root = -1){
    ok = 1;
    if(root != -1) this->root = root;
    function<void(Int,Int)> dfs = [&](Int pos,Int pre){
      parent[pos] = pre;
      for(Int to:G[pos]) if(to != pre) dfs(to, pos);
    };
    dfs(this->root, -1);
  }
  Int get(Int u){assert(ok); assert(0 <= u && u < V); return parent[u];}

};

Int N, T;
vector<vector<P> > G;
TreeParent parS, parE;
vector<Int> edge;

Int valid = 1;
void dfs(Int pos, Int pre, Int start, TreeParent &par){

  for(P p:G[pos]){
    Int to, i; tie(to, i) = p;
    if(to == pre || par.get(pos) == to) continue;
    dfs(to, pos, 0, par);
  }

  sort(G[pos].begin(), G[pos].end(), [&](auto a, auto b)
       {return edge[a.second] < edge[b.second];});

  Int sum = start==1? 0:T;
  for(P p:G[pos]){
    Int to, i; tie(to, i) = p;
    if(to == pre || par.get(pos) == to) continue;
    valid &= edge[i] - sum > 0; //帰ってこれるか判定
    sum += T;
  }

  for(auto p:G[pos]){
    Int to, i; tie(to, i) = p;
    edge[i] -= sum;
  }
}

void dfs2(Int pos, Int pre, Int flag, TreeParent &par){ //SからEにいく
  Int sum = T;
  if(par.get(pos) != -1){ //pos != E
    for(P p:G[pos]){
      Int to, i; tie(to, i) = p;
      if(to == pre || par.get(pos) == to) continue; //最初に分かれ道にいく
      dfs2(to, pos, 0, par);
    }

    sort(G[pos].begin(), G[pos].end(), [&](auto a, auto b){return edge[a.second] < edge[b.second];});
    for(P p:G[pos]){
      Int to, i; tie(to, i) = p;
      if(to == pre || par.get(pos) == to) continue; //最初に分かれ道にいく
      valid &= edge[i] - sum > 0; //帰ってこれるか判定
      sum += T;
    }

    for(P p:G[pos]){
      Int to, i; tie(to, i) = p;
      if(to == pre || par.get(pos) != to) continue; //Eの方向にいく
      dfs2(to, pos,1, par);
      valid &= edge[i] - sum > 0;
      sum += T;
    }
  }

  if(flag == 0){
    for(auto p:G[pos]){
      Int to, i; tie(to, i) = p;
      edge[i] -= sum;
    }
  }
}

signed main(){
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  Int S, E;
  cin>>N>>T>>S>>E; S--, E--;

  G.resize(N);
  parS = TreeParent(N, S);
  parE = TreeParent(N, E);
  edge.resize(N-1);
  for(Int i=0;i<N-1;i++){
    Int a, b, w;
    cin>>a>>b>>w; a--, b--;
    G[a].push_back(P(b, i));
    G[b].push_back(P(a, i));
    parS.add_edge(a, b);
    parE.add_edge(a, b);
    edge[i] = w;
  }

  parS.build(); parE.build();

  if(S == E){
    dfs(S, -1, 1, parE);
    cout<<(valid? "Yes":"No")<<endl;
    return 0;
  }

  dfs(S, -1, 1, parE);

  for(auto p:G[S]){
    Int to, i; tie(to, i) = p;
    if(to == parE.get(S)) valid &= edge[i] > 0;
  }
  dfs2(parE.get(S), S, 1, parE);
  dfs(E, -1, 1, parS);

  cout<<(valid? "Yes":"No")<<endl;



  return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 27740
final_rank: 14

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>

#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>

#include <functional>
#include <cassert>

#include <unistd.h>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

vector<pair<int, int> > G[SIZE];

int ok[SIZE];

int N, T, S, E;
ll w[SIZE];
int counter[SIZE];

bool dfs1(int now, int back = -1) {
  bool res =  now == E;

  for(auto p : G[now]) {
    int to = p.first;
    int idx = p.second;
    if(to == back) continue;

    counter[now]++;
    res |= dfs1(to, now);
    counter[now]++;
  }

  return ok[now] = res;
}

priority_queue<pair<ll,pair<int,int> > > pq_[SIZE];
bool visited[SIZE];

pair<bool,bool> dfs2(int now, int back = -1) {
  auto &pq = pq_[now];
  bool res = true;

  visited[now] = true;

  for(auto p : G[now]) {
    int to = p.first;
    int idx = p.second;

    w[idx] -= T;

    if(to == back) continue;

    ll cost = w[idx];
    cost -= (ll)(counter[to] - 1) * T;
    cost += LLINF * ok[to];

    pq.push({-cost, {idx, to}});

  }

  while(pq.size()) {
    auto p = pq.top();
    pq.pop();

    int to = p.second.second;
    int idx = p.second.first;

    if (w[idx] <= 0) return {false, true};
    auto tmp = dfs2(to, now);
    if (tmp.second) return tmp;
    if (w[idx] <= 0) return {false, true};
    debug(idx);
    debug(w[idx]);

    res &= tmp.first;

    for(auto q : G[now]) {
      int idx = q.second;
      w[idx] -= T;
    }
  }

  return {res, now == E};
}


int main(){
  scanf("%d%d%d%d", &N, &T, &S, &E);
  S--; E--;

  for(int i=0; i<N-1; i++) {
    int a, b;
    scanf("%d%d%lld", &a, &b, w+i);
    a--; b--;

    if (a == S || b == S) {
      w[i] += T;
    }

    G[a].push_back({b, i});
    G[b].push_back({a, i});
  }

  dfs1(S);

  auto res = dfs2(S);

  if(res.first) {
    puts("Yes");

    for(int i=0; i<N; i++) assert(visited[i]);

  } else {
    puts("No");
  }

  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 22276
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

int N, S, E;
int64_t T;
vector<pair<int, int64_t>> edges[100000];

int nxt[100000];

bool dfs1(int i, int par){
    nxt[i] = -1;
    bool res = (i==E);
    for(auto& p : edges[i]){
        int j = p.first;
        if(j != par){
            if(dfs1(j, i)){
                res = true;
                nxt[i] = j;
            }
        }
    }
    return res;
}

int num[100000];

void fail(){
    cout << "No" << endl;
    exit(0);
}

void dfs2(int i, int par){
    vector<pair<int, int64_t>> child;
    for(auto& p : edges[i]) if(p.first != par) if(p.first != nxt[i]) child.push_back(p);
    sort(child.begin(), child.end(), [&](auto e1, auto e2){
        return e1.second - T*edges[e1.first].size() < e2.second - T*edges[e2.first].size();
    });
    for(auto& p : edges[i]) if(p.first != par) if(p.first == nxt[i]) child.push_back(p);
    for(auto& p : child){
        int j = p.first;
        int64_t c = p.second;
        if(T*(num[i]+num[j]) >= c) fail();
        num[j]++;
        dfs2(j, i);
        if(nxt[i] != j){
            if(T*(num[i]+num[j]) >= c) fail();
            num[i]++;
        }
    }
}

int main(){
    cin >> N >> T >> S >> E;
    S--; E--;
    for(int i=0; i<N-1; i++){
        int a, b, c;
        cin >> a >> b >> c;
        edges[a-1].emplace_back(b-1, c);
        edges[b-1].emplace_back(a-1, c);
    }

    dfs1(S, -1);
    dfs2(S, -1);
    cout << "Yes" << endl;
}
accuracy: 1
time_ms: 90
memory_kb: 15136
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define ll long long

//#define TEST

struct edge {
	ll from, to, weight;
	ll cnt = 0;
	edge(ll f, ll t, ll w) {
		from = f;
		to = t;
		weight = w;
	}
};

ll n, t, s, e;
vector<vector<ll>> g; // 隣接リスト
vector<ll> tree; // tree[i] := iの親
vector<edge> es;

void dfs(ll s) {
	for (auto to : g[s]) {
		if (tree[to] == -1) {
			tree[to] = s;
			dfs(to);
		}
	}
}

signed main() {
	cin >> n >> t >> s >> e;
	--s; --e;

	vector<vector<ll>> g_(n);
	g = g_;
	vector<ll> tree_(n, -1);
	tree = tree_;

	for (ll i = 0; i < n - 1; ++i) {
		ll a, b, w;
		cin >> a >> b >> w;
		--a; --b;
		g[a].push_back(b);
		g[b].push_back(a);
		edge eab(a, b, w);
		es.push_back(eab);
	}

	tree[s] = s;
	dfs(s);

#ifdef TEST
	for (auto p : tree)
		cout << p << " ";
	cout << endl;
#endif

	vector<ll> cnt(n, 1); // 頂点iを何回訪れるか
	cnt[s] -= 2;
	for (auto p : tree)
		cnt[p]++;

	ll now = e; ll parent = tree[e];
	while (now != parent) {
		cnt[parent]--;
		now = parent;
		parent = tree[now];
	}

#ifdef TEST
	for (auto ci : cnt)
		cout << ci << " ";
	cout << endl;
#endif

	for (auto& ei : es) {
		ei.cnt = cnt[ei.from] + cnt[ei.to] - 1;
	}

	for (auto ei : es) {
		if (ei.weight <= ei.cnt * t) {
			cout << "No" << endl;
			return 0;
		}
	}

	cout << "Yes" << endl;

	return 0;
}
accuracy: 0.9714285714285714
time_ms: 80
memory_kb: 17712
final_rank: 19