Problem:
Problem F: Timing
Problem
$N$頂点$M$辺の無向グラフが与えられる。各頂点には相異なる$1$から$N$までの番号が定められている。あなたは時刻$0$に頂点$S$を出発し、頂点$G$まで移動したい。各辺にはパラメータ$a, b$が設定されていて、時刻$t$にその辺の片側の頂点から出発した場合、もう片側の頂点には時刻$t+ceil\left(\cfrac{b}{t+a}\right)$に到達することがわかっている。ここで、$ceil(x)$は$x$以上の最小の整数を表す。また、各頂点では任意の非負整数時間を余分に消費することができる。つまり、時刻$t$にある頂点にいるとき、任意の非負整数$k$を選び、時刻$t+k$になるまで待機することができる。最速最強アルゴリズマーを目指すあなたは、頂点$S$から頂点$G$まで移動するためにかかる時間の最小値を求めたくなった。
Input
入力は以下の形式で与えられる。
$N$ $M$ $S$ $G$
$U_1$ $V_1$ $A_1$ $B_1$
$U_2$ $V_2$ $A_2$ $B_2$
:
$U_M$ $V_M$ $A_M$ $B_M$
$1$行目に、与えられるグラフの頂点数$N$、辺数$M$、スタートの頂点番号$S$、ゴールの頂点番号$G$が空白区切りで与えられる。
続く$M$行に、各辺の情報が空白区切りで与えられる。$i$行目の情報は、頂点$U_i$と頂点$V_i$の間に$(a, b) = (A_i, B_i)$であるような辺が存在することを表す。
Constraints
入力は以下の条件を満たす。
$1 \le N, M \le 2 \times 10^5$
$1 \le S, G \le N$, $S \neq G$
$1 \le U_i, V_i \le N$, $U_i \neq V_i (1 \le i \le M)$
$1 \le A_i, B_i \le 10^{15} (1 \le i \le M)$
与えられる入力は全て整数である
Output
頂点$S$から頂点$G$まで移動するためにかかる時間の最小値を出力せよ。頂点$S$から頂点$G$に移動できない場合は、代わりに$-1$を出力せよ。
Sample Input 1
2 1 1 2
1 2 1 100
Sample Output 1
19
頂点$1$で時間を$9$消費し、時刻$9$に辺$1$を使うと、辺の所要時間は$ceil\left(\cfrac{100}{10}\right) = 10$となり、時刻$19$に頂点$2$に到達できる。これが最短である。
Sample Input 2
2 1 1 2
1 2 50 100
Sample Output 2
2
時刻$0$に辺$1$を使うのが最適である。
Sample Input 3
3 1 1 3
1 2 1 1
Sample Output 3
-1
頂点$S$から頂点$G$に移動できない場合もある。
Sample Input 4
3 3 1 3
1 2 1 1
2 3 1 6
2 3 50 100
Sample Output 4
3
Sample Input 5
3 3 1 3
1 2 10 100
2 3 1 6
2 3 50 100
Sample Output 5
11

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 1;
vector<pair<int, pair<ll, ll> > > g[N];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m, S, G;
    cin >> n >> m >> S >> G;
    S--;
    G--;
    for (int i = 0; i < m; i++) {
        int u, v;
        ll a, b;
        cin >> u >> v >> a >> b;
        u--;
        v--;
        g[u].push_back({v, {a, b}});
        g[v].push_back({u, {a, b}});
    }
    auto get = [&](ll x, ll a, ll b) {
        if (a + x > b) return x + 1;
        ll l = x, r = b;
        while (r - l > 2) {
            ll m1 = l + (r - l) / 3, m2 = r - (r - l) / 3;
            double f1 = m1 + (double) (b + m1 + a - 1.00) / (m1 + a),
                    f2 = m2 + (double) (b + m2 + a - 1.00) / (m2 + a);
            if (f1 < f2) {
                r = m2;
            } else
                l = m1;
        }
        ll ans = 1e18;
        for (ll i = l; i <= r; i++)
            ans = min(ans, i + (i + a + b - 1) / (a + i));
        return ans;
    };
    vector<ll> d(n, 1e18);
    d[S] = 0;
    set<pair<ll, int> > st = {{0, S}};
    while (!st.empty()) {
        auto [w, v] = *st.begin();
        st.erase(st.begin());
        for (auto [to, ab]: g[v]) {
            auto [a, b] = ab;
            ll wx = get(w, a, b);
            if (d[to] > wx) {
                st.erase({d[to], to});
                d[to] = wx;
                st.insert({d[to], to});
            }
        }
    }
    cout << (d[G] == 1e18 ? -1 : d[G]) << '\n';
    return 0;
}
accuracy: 1
time_ms: 470
memory_kb: 34560
final_rank: 10

code_snippet: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sstream>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned int ull;
typedef pair<int,int> pil;
const ll ll_INF = 0x3f3f3f3f3f3f3f3f;
const int int_INF = 0x3f3f3f3f;
const double EPS = 1e-7;
#define R register
#define _max(a,b)  ((a)>(b)?(a):(b))
#define _min(a,b)  ((a)<(b)?(a):(b))
#define _abs(a)    ((a)> 0 ?(a):-(a))
#define _swap(a,b) ((a)^=(b)^=(a)^=(b))
#define _eql(x,y)  (_abs((x) - (y))<EPS)
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
const int MX = 1000010;
const int MOD= 1e9+7;
ll _r() {
    ll x = 0, f = 1;
    char c = getchar();
    while (c > '9' || c < '0') { if (c == '-')f = -1; c = getchar(); }
    while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return f==-1?-x:x;
}
int n,m,st,ed;

struct Node {
    ll a,b;
	int v;
	int _next;
}e[MX<<1];
int head[MX], cnt = 0;
void addedge(int u, int v, ll a, ll b) {
	e[++cnt].v = v;
	e[cnt].a = a;
    e[cnt].b = b;
	e[cnt]._next = head[u];
	head[u] = cnt;
}
priority_queue<pil, vector<pil>, greater<pil> > q;
int vis[MX] = { 0 };
ll dis[MX]={0};
ll calc(ll a,ll b,ll t){
    if(b<=t+a)
        return t+1;
    //等待时间x,求导求极小值
    ll x=sqrt(b)-t-a;
    ll temp=t+ceil((double)(b)/(t+a));
    if(x>=0)
        temp=_min(temp,t+x+(ll)ceil((double)(b)/(t+a+x)));
    if(x-1>=0)
        temp=_min(temp,t+x-1+(ll)ceil((double)(b)/(t+a+x-1)));
    if(x+1>=0)
        temp=_min(temp,t+x+1+(ll)ceil((double)(b)/(t+a+x+1)));
    return (ll)temp;
}
void dijkstra(int u) {
	q.push(make_pair(0, u));
	dis[u] = 0;
	while (!q.empty()) {
		pil a = q.top(); q.pop();
		u = a.second;
		if (vis[u])continue;
		vis[u] = 1;
		for (int i = head[u]; i; i = e[i]._next) {
            ll temp=calc(e[i].a,e[i].b,dis[u] );
			if (temp< dis[e[i].v]) {
				dis[e[i].v] = temp;
				q.push(make_pair(dis[e[i].v], e[i].v));
			}
		}
	}
}
void Init() {
    n=_r(),m=_r(),st=_r(),ed=_r();
    for(int i=0;i<=n;i++){
        dis[i]=ll_INF;
    }
    int u,v;
    ll a,b;
    for(int i=0;i<m;i++){    
        u=_r(),v=_r();
        a=_r(),b=_r();
        addedge(u,v,a,b);
        addedge(v,u,a,b);
    }
}

void solve() {
    dijkstra(st);
    printf("%lld\n",dis[ed]==ll_INF?-1:dis[ed]);
}
int main() {
#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif
    Init();
    solve();
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 16852
final_rank: 1

code_snippet: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sstream>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned int ull;
typedef pair<int,int> pil;
const ll ll_INF = 0x3f3f3f3f3f3f3f3f;
const int int_INF = 0x3f3f3f3f;
const double EPS = 1e-7;
#define R register
#define _max(a,b)  ((a)>(b)?(a):(b))
#define _min(a,b)  ((a)<(b)?(a):(b))
#define _abs(a)    ((a)> 0 ?(a):-(a))
#define _swap(a,b) ((a)^=(b)^=(a)^=(b))
#define _eql(x,y)  (_abs((x) - (y))<EPS)
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
const int MX = 1000010;
const int MOD= 1e9+7;
ll _r() {
    ll x = 0, f = 1;
    char c = getchar();
    while (c > '9' || c < '0') { if (c == '-')f = -1; c = getchar(); }
    while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return f==-1?-x:x;
}
int n,m,st,ed;

struct Node {
    int a,b;
	int v;
	int _next;
}e[MX<<1];
int head[MX], cnt = 0;
void addedge(int u, int v, int a, int b) {
	e[++cnt].v = v;
	e[cnt].a = a;
    e[cnt].b = b;
	e[cnt]._next = head[u];
	head[u] = cnt;
}
priority_queue<pil, vector<pil>, greater<pil> > q;
int vis[MX] = { 0 };
ll dis[MX]={0};
ll calc(int a,int b,ll t){
    if(b<=t+a)
        return t+1;
    //等待时间x,求导求极小值
    ll x=ceil(sqrt(b))-t-a;
    ll temp=t+ceil((double)(b)/(t+a));
    if(x>=0)
        temp=_min(temp,t+x+(ll)ceil((double)(b)/(t+a+x)));
    if(x-1>=0)
        temp=_min(temp,t+x-1+(ll)ceil((double)(b)/(t+a+x-1)));
    if(x+1>=0)
        temp=_min(temp,t+x+1+(ll)ceil((double)(b)/(t+a+x+1)));
    return (ll)temp;
}
void dijkstra(int u) {
	q.push(make_pair(0, u));
	dis[u] = 0;
	while (!q.empty()) {
		pil a = q.top(); q.pop();
		u = a.second;
		if (vis[u])continue;
		vis[u] = 1;
		for (int i = head[u]; i; i = e[i]._next) {
            ll temp=calc(e[i].a,e[i].b,dis[u] );
			if (temp< dis[e[i].v]) {
				dis[e[i].v] = temp;
				q.push(make_pair(dis[e[i].v], e[i].v));
			}
		}
	}
}
void Init() {
    n=_r(),m=_r(),st=_r(),ed=_r();
    for(int i=0;i<=n;i++){
        dis[i]=ll_INF;
    }
    for(int i=0;i<m;i++){
        int u,v,a,b;
        u=_r(),v=_r(),a=_r(),b=_r();
        addedge(u,v,a,b);
        addedge(v,u,a,b);
    }
}

void solve() {
    dijkstra(st);
    printf("%lld\n",dis[ed]==ll_INF?-1:dis[ed]);
}
int main() {
#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif
    Init();
    solve();
    return 0;
}
accuracy: 0.2698412698412698
time_ms: 80
memory_kb: 10972
final_rank: 16

code_snippet: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sstream>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned int ull;
typedef pair<int,int> pil;
const ll ll_INF = 0x3f3f3f3f3f3f3f3f;
const int int_INF = 0x3f3f3f3f;
const double EPS = 1e-7;
#define R register
#define _max(a,b)  ((a)>(b)?(a):(b))
#define _min(a,b)  ((a)<(b)?(a):(b))
#define _abs(a)    ((a)> 0 ?(a):-(a))
#define _swap(a,b) ((a)^=(b)^=(a)^=(b))
#define _eql(x,y)  (_abs((x) - (y))<EPS)
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
const int MX = 1000010;
const int MOD= 1e9+7;
ll _r() {
    ll x = 0, f = 1;
    char c = getchar();
    while (c > '9' || c < '0') { if (c == '-')f = -1; c = getchar(); }
    while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return f==-1?-x:x;
}
int n,m,st,ed;

struct Node {
    int a,b;
	int v;
	int _next;
}e[MX<<1];
int head[MX], cnt = 0;
void addedge(int u, int v, int a, int b) {
	e[++cnt].v = v;
	e[cnt].a = a;
    e[cnt].b = b;
	e[cnt]._next = head[u];
	head[u] = cnt;
}
priority_queue<pil, vector<pil>, greater<pil> > q;
int vis[MX] = { 0 };
ll dis[MX]={0};
ll calc(int a,int b,ll t){
    if(b<=t+a)
        return t+1;
    //求导求极小值
    ll x=(ll)sqrt(b)-t-a;
    ll temp=t+ceil((double)(b)/(t+a));
    if(x>0)
        temp=_min(temp,t+x+(int)ceil((double)(b)/(t+a+x)));
    if(x-1>0)
        temp=_min(temp,t+x-1+(int)ceil((double)(b)/(t+a+x-1)));
    if(x+1>0)
        temp=_min(temp,t+x+1+(int)ceil((double)(b)/(t+a+x+1)));
    return (ll)temp;
}
void dijkstra(int u) {
	q.push(make_pair(0, u));
	dis[u] = 0;
	while (!q.empty()) {
		pil a = q.top(); q.pop();
		u = a.second;
		if (vis[u])continue;
		vis[u] = 1;
		for (int i = head[u]; i; i = e[i]._next) {
            ll temp=calc(e[i].a,e[i].b,dis[u] );
			if (temp< dis[e[i].v]) {
				dis[e[i].v] = temp;
				q.push(make_pair(dis[e[i].v], e[i].v));
			}
		}
	}
}
void Init() {
    n=_r(),m=_r(),st=_r(),ed=_r();
    for(int i=0;i<=n;i++){
        dis[i]=ll_INF;
    }
    for(int i=0;i<m;i++){
        int u,v,a,b;
        u=_r(),v=_r(),a=_r(),b=_r();
        addedge(u,v,a,b);
        addedge(v,u,a,b);
    }
}

void solve() {
    dijkstra(st);
    printf("%lld\n",dis[ed]==ll_INF?-1:dis[ed]);
}
int main() {
#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif
    Init();
    solve();
    return 0;
}
accuracy: 0.2698412698412698
time_ms: 80
memory_kb: 11040
final_rank: 17

code_snippet: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sstream>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned int ull;
typedef pair<int,int> pil;
const ll ll_INF = 0x3f3f3f3f3f3f3f3f;
const int int_INF = 0x3f3f3f3f;
const double EPS = 1e-7;
#define R register
#define _max(a,b)  ((a)>(b)?(a):(b))
#define _min(a,b)  ((a)<(b)?(a):(b))
#define _abs(a)    ((a)> 0 ?(a):-(a))
#define _swap(a,b) ((a)^=(b)^=(a)^=(b))
#define _eql(x,y)  (_abs((x) - (y))<EPS)
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
const int MX = 1000010;
const int MOD= 1e9+7;
ll _r() {
    ll x = 0, f = 1;
    char c = getchar();
    while (c > '9' || c < '0') { if (c == '-')f = -1; c = getchar(); }
    while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return f==-1?-x:x;
}
int n,m,st,ed;

struct Node {
    int a,b;
	int v;
	int _next;
}e[MX<<1];
int head[MX], cnt = 0;
void addedge(int u, int v, int a, int b) {
	e[++cnt].v = v;
	e[cnt].a = a;
    e[cnt].b = b;
	e[cnt]._next = head[u];
	head[u] = cnt;
}
priority_queue<pil, vector<pil>, greater<pil> > q;
int vis[MX] = { 0 };
ll dis[MX]={0};
ll calc(int a,int b,ll t){
    if(b<=t+a)
        return t+1;
    //求导求极小值
    int x=(int)sqrt(b)-t-a;
    int temp=t+ceil((double)(b)/(t+a));
    if(x>0)
        temp=_min(temp,t+x+(int)ceil((double)(b)/(t+a+x)));
    if(x-1>0)
        temp=_min(temp,t+x-1+(int)ceil((double)(b)/(t+a+x-1)));
    if(x+1>0)
        temp=_min(temp,t+x+1+(int)ceil((double)(b)/(t+a+x+1)));
    return (ll)temp;
}
void dijkstra(int u) {
	q.push(make_pair(0, u));
	dis[u] = 0;
	while (!q.empty()) {
		pil a = q.top(); q.pop();
		u = a.second;
		if (vis[u])continue;
		vis[u] = 1;
		for (int i = head[u]; i; i = e[i]._next) {
            ll temp=calc(e[i].a,e[i].b,dis[u] );
			if (temp< dis[e[i].v]) {
				dis[e[i].v] = temp;
				q.push(make_pair(dis[e[i].v], e[i].v));
			}
		}
	}
}
void Init() {
    n=_r(),m=_r(),st=_r(),ed=_r();
    for(int i=0;i<=n;i++){
        dis[i]=ll_INF;
    }
    for(int i=0;i<m;i++){
        int u,v,a,b;
        u=_r(),v=_r(),a=_r(),b=_r();
        addedge(u,v,a,b);
        addedge(v,u,a,b);
    }
}

void solve() {
    dijkstra(st);
    printf("%lld\n",dis[ed]==ll_INF?-1:dis[ed]);
}
int main() {
#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif
    Init();
    solve();
    return 0;
}
accuracy: 0.2698412698412698
time_ms: 80
memory_kb: 11144
final_rank: 19

code_snippet: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sstream>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned int ull;
typedef pair<int,int> pil;
const ll ll_INF = 0x3f3f3f3f3f3f3f3f;
const int int_INF = 0x3f3f3f3f;
const double EPS = 1e-7;
#define R register
#define _max(a,b)  ((a)>(b)?(a):(b))
#define _min(a,b)  ((a)<(b)?(a):(b))
#define _abs(a)    ((a)> 0 ?(a):-(a))
#define _swap(a,b) ((a)^=(b)^=(a)^=(b))
#define _eql(x,y)  (_abs((x) - (y))<EPS)
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
const int MX = 1000010;
const int MOD= 1e9+7;
ll _r() {
    ll x = 0, f = 1;
    char c = getchar();
    while (c > '9' || c < '0') { if (c == '-')f = -1; c = getchar(); }
    while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return f==-1?-x:x;
}
int n,m,st,ed;

struct Node {
    int a,b;
	int v;
	int _next;
}e[MX<<1];
int head[MX], cnt = 0;
void addedge(int u, int v, int a, int b) {
	e[++cnt].v = v;
	e[cnt].a = a;
    e[cnt].b = b;
	e[cnt]._next = head[u];
	head[u] = cnt;
}
priority_queue<pil, vector<pil>, greater<pil> > q;
int vis[MX] = { 0 };
ll dis[MX]={0};
ll calc(int a,int b,ll t){
    if(b<=t+a)
        return t+1;
    //求导求极小值
    double x=(double)sqrt(b)-t-a;
    double temp=t+ceil((double)(b)/(t+a));
    if(ceil(x)>0)
        temp=_min(temp,t+ ceil(x)+ceil((double)(b)/(t+a+ ceil(x))));
    if(floor(x)>0)
        temp=_min(temp,t+floor(x)+ceil((double)(b)/(t+a+floor(x))));
    return (ll)temp;
}
void dijkstra(int u) {
	q.push(make_pair(0, u));
	dis[u] = 0;
	while (!q.empty()) {
		pil a = q.top(); q.pop();
		u = a.second;
		if (vis[u])continue;
		vis[u] = 1;
		for (int i = head[u]; i; i = e[i]._next) {
            ll temp=calc(e[i].a,e[i].b,dis[u] );
			if (temp< dis[e[i].v]) {
				dis[e[i].v] = temp;
				q.push(make_pair(dis[e[i].v], e[i].v));
			}
		}
	}
}
void Init() {
    n=_r(),m=_r(),st=_r(),ed=_r();
    for(int i=0;i<=n;i++){
        dis[i]=ll_INF;
    }
    for(int i=0;i<m;i++){
        int u,v,a,b;
        u=_r(),v=_r(),a=_r(),b=_r();
        addedge(u,v,a,b);
        addedge(v,u,a,b);
    }
}

void solve() {
    dijkstra(st);
    printf("%lld\n",dis[ed]==ll_INF?-1:dis[ed]);
}
int main() {
#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif
    Init();
    solve();
    return 0;
}
accuracy: 0.2698412698412698
time_ms: 80
memory_kb: 11124
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
using ll = long long int;
using P = pair<ll, int>;
struct Edge{
    int to;
    ll a;
    ll b;
};

int main(){
    int n, m, s, g;
    cin >> n >> m >> s >> g;
    s--; g--;
    vector<vector<Edge>> G(n);
    for(int i = 0; i < m; i++){
        ll u, v, a, b;
        cin >> u >> v >> a >> b;
        u--; v--;
        G[u].push_back({(int)v, a, b});
        G[v].push_back({(int)u, a, b});
    }

    vector<ll> dist(n, 1LL << 60);
    priority_queue<P, vector<P>, greater<P>> Q;
    dist[s] = 0;
    Q.push({0, s});
    auto newtime = [&](const Edge &e, ll curtime){
        ll ans = 1LL << 60;
        ll start = max(curtime, (ll)sqrt(e.b)-e.a-20);
        for(ll t = start; t < start+40; t++) ans = min(ans, t+(e.b+t+e.a-1)/(t+e.a));
        return ans;
    };
    while(Q.size()){
        P cur = Q.top(); Q.pop();
        if(dist[cur.second] < cur.first) continue;

        for(auto &p: G[cur.second]){
            ll ntime = newtime(p, dist[cur.second]);
            if(dist[p.to] > ntime){
                dist[p.to] = ntime;
                Q.push({ntime, p.to});
            }
        }
    }

    if(dist[g] < 1LL << 60) cout << dist[g] << endl;
    else cout << -1 << endl;
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 28648
final_rank: 8

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <tuple>
#include <cmath>
using namespace std;
template<class T> T ceil(T a, T b) { return a / b + !!(a % b); }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

using pll = pair<long long, long long>;
using edge = pair<int, pll>;
using Graph = vector<vector<edge>>;
int main() {
    int n, m; cin >> n >> m;
    int s, t; cin >> s >> t; s--, t--;
    Graph g(n);
    while (m--) {
        int u, v; cin >> u >> v; u--, v--;
        long long a, b; cin >> a >> b;
        g[u].emplace_back(v, pll(a, b));
        g[v].emplace_back(u, pll(a, b));
    }
    using T = long long;
    const T INF = numeric_limits<T>::max();
    vector<T> dp(n, INF);
    using P = pair<T, int>;
    priority_queue<P, vector<P>, greater<P>> que;
    que.emplace(dp[s] = 0, s);
    auto calc = [&](long long cur, pll &p) {
        long long a, b; tie(a, b) = p;
        auto f = [&](long long t) { return t + ceil(b, t + a); };
        long long mi = f(cur), t = sqrt(b) - a;
        for (int d: {-1, 0, 1}) if (cur <= t + d) chmin(mi, f(t + d));
        return mi;
    };
    while (!que.empty()) {
        long long cur; int u; tie(cur, u) = que.top(); que.pop();
        if (dp[u] < cur) continue;
        for (auto &e: g[u]) {
            int v = e.first;
            if (chmin(dp[v], calc(cur, e.second))) que.emplace(dp[v], v);
        }
    }
    cout << (dp[t] == INF ? -1 : dp[t]) << endl;
    return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 26548
final_rank: 6

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 200005

struct Edge{

	int from,to;
	ll A,B;
};

struct Info{
	Info(int arg_to,int arg_index){
		to = arg_to;
		edge_index = arg_index;
	}
	int to,edge_index;
};

struct State{
	State(int arg_node_id,double arg_sum_dist){
		node_id = arg_node_id;
		sum_dist = arg_sum_dist;
	}
	bool operator<(const struct State &arg) const{

		return sum_dist > arg.sum_dist; //総距離の昇順(PQ)
	}

	int node_id;
	double sum_dist;
};

int N,M,start,goal;
double min_dist[SIZE];
Edge edge[SIZE];
vector<Info> G[SIZE];

int main(){

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

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

		scanf("%d %d %lld %lld",&edge[i].from,&edge[i].to,&edge[i].A,&edge[i].B);
		edge[i].from--;
		edge[i].to--;
		G[edge[i].from].push_back(Info(edge[i].to,i));
		G[edge[i].to].push_back(Info(edge[i].from,i));
	}

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

		min_dist[i] = DBL_MAX;
	}

	min_dist[start] = 0;

	priority_queue<State> Q;
	Q.push(State(start,0));

	while(!Q.empty()){

		if(Q.top().sum_dist > min_dist[Q.top().node_id]+EPS){

			Q.pop();

		}else if(Q.top().node_id == goal){

			printf("%.0lf\n",Q.top().sum_dist);
			return 0;

		}else{

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

				int next = G[Q.top().node_id][i].to;
				int index = G[Q.top().node_id][i].edge_index;
				ll A = edge[index].A;
				ll B = edge[index].B;

				double base = sqrt(B)-A;
				double next_dist;

				if(base <= Q.top().sum_dist){

					next_dist = ceil(Q.top().sum_dist+(B/(Q.top().sum_dist+A)));

				}else{

					next_dist = ceil(base+(B/(base+A)));
				}

				if(min_dist[next] > next_dist){
					min_dist[next] = next_dist;
					Q.push(State(next,next_dist));
				}
			}

			Q.pop();
		}
	}

	printf("-1\n");

	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 26700
final_rank: 2

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

using ll=long long;
const ll INF=1e18;
const ll WIDTH=1;
struct Edge{
  int to;
  ll a,b;
};
using Graph=vector<vector<Edge>>;
ll f(ll t,ll a,ll b){
  return t+b/(t+a)+(int)(b%(t+a)>0);
}

using dbl=double;
ll calc(ll t,ll a,ll b){
  dbl X=2*a+1;
  dbl Y=(dbl)(a)*(a+1)-b;
  dbl t0=(-X+sqrt(X*X-4*Y))/2;
  ll res=f(t,a,b);
  ll tx=t0;
  for(int i=-WIDTH;i<=WIDTH;i++){
    ll topt=tx+i;
    if(topt<t) continue;
    res=min(res,f(topt,a,b));
  }

  return res;
}
vector<ll> Dijkstra(int s,Graph& g){
  int n=g.size();
  vector<ll> t(n,INF);
  using Item=pair<ll,int>;
  priority_queue<Item,vector<Item>,greater<>> que;
  t[s]=0;
  que.push({0LL,s});
  vector<int> used(n,false);
  while(!que.empty()){
    auto tmp=que.top(); que.pop();
    int v=tmp.second;
    if(t[v]<tmp.first) continue;
    assert(!used[v]);
    used[v]=true;
    for(Edge& e:g[v]){
      ll tot=calc(t[v],e.a,e.b);
      assert(t[v]<=tot);
      if(tot<t[e.to]){
	t[e.to]=tot;
	que.push({tot,e.to});
      }
    }
  }
  return t;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
  int n,m;
  int S,G;
  cin>>n>>m>>S>>G;
  S--,G--;
  Graph g(n);
  for(int i=0;i<m;i++){
    int u,v;
    ll a,b;
    cin>>u>>v>>a>>b;
    u--,v--;
    g[u].push_back(Edge{v,a,b});
    g[v].push_back(Edge{u,a,b});
  }

  auto t=Dijkstra(S,g);

  cout<<(t[G]>=INF ? -1LL : t[G])<<endl;
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 27292
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<P,P> PP;
const ll MOD = 1000000007;
const int IINF = INT_MAX;
const ll LLINF = LLONG_MAX;
const int MAX_N = int(2e5 + 5);
const int MAX_V = int(2e5 + 5);
const double EPS = 1e-10;
const int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define SORT(v) sort((v).begin(), (v).end())
#define ALL(v) (v).begin(), (v).end()

struct edge {
    ll from, to, a, b;
    edge(ll u, ll v, ll a, ll b) : from(u), to(v), a(a), b(b){};
};

vector<edge> G[MAX_V];
ll dmin[MAX_V];

void add_edge(ll u, ll v, ll a, ll b) {
    G[u].push_back(edge(u, v, a, b));
    G[v].push_back(edge(v, u, a, b));
}

ll f(ll b, ll a, ll x) { return ll(ceil(b / double(a + x) + double(x))); }

void dijkstra(int s) {
    priority_queue<P, vector<P>, greater<P> > que;  //小さいものから取り出す
    fill(dmin, dmin + MAX_V, LLINF);
    dmin[s] = 0;
    que.push(P(0, s));

    while (!que.empty()) {
        P p = que.top();
        que.pop();
        int v = p.second;
        if (dmin[v] < p.first) continue;
        for (auto &e : G[v]) {
            ll k = max(0.0, pow(e.b, 0.5) - (e.a + dmin[v])), cost;
            cost = f(e.b, e.a + dmin[v], 0);
            if (k > 0) {
                cost = min(cost,min(f(e.b,e.a+dmin[v],floor(k)),f(e.b,e.a+dmin[v],ceil(k))));
            }
            if (dmin[e.to] > dmin[v] + cost) {
                dmin[e.to] = dmin[v] + cost;
                que.push(P(dmin[e.to], e.to));
            }
        }
    }
}

int main() {
    ll n, m, s, g;
    cin >> n >> m >> s >> g;
    REP(i, m) {
        ll u, v, a, b;
        cin >> u >> v >> a >> b;
        add_edge(u, v, a, b);
    }
    dijkstra(s);
    cout << (dmin[g]!=LLINF?dmin[g]:-1) << endl;
    return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 32316
final_rank: 9

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

using namespace std;
namespace sub {
    template<typename T>
    constexpr typename std::enable_if<std::is_integral<T>::value, T>::type
    inf_sub() {
        return std::numeric_limits<T>::max() / 2 - 1000;
    }

    template<typename T>
    constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
    inf_sub() {
        return std::min(std::numeric_limits<T>::max() / 2 - 1000, T(1e50));
    }
}  // namespace sub

template<typename T>
constexpr T inf() {
    static_assert(std::is_arithmetic<T>::value, "T must be arithmetic value");
    return sub::inf_sub<T>();
}

template<typename T>
constexpr T zero() {
    static_assert(std::is_arithmetic<T>::value, "T must be arithmetic value");
    return T(0);
}

const long double pi = acos(-1.0);

template<class edge_t>
class graph_t {
    std::vector<std::vector<edge_t>> g;

public:
    using reference = std::vector<edge_t> &;
    using const_reference = const std::vector<edge_t> &;
    using iterator = typename std::vector<edge_t>::iterator;

    graph_t() : g(0) { ; }

    graph_t(int n) : g(n) { ; }

    int size() const { return g.size(); }

    void push_back(const std::vector<edge_t> &es) { g.push_back(es); }

    reference operator[](int x) { return g[x]; }

    const_reference operator[](int x) const { return g[x]; }

    iterator &begin() { return begin(g); }

    iterator &end() { return end(g); }
};


typedef __int128 int128;

/**
 * func: (long long) -> boolean
 * binary_search() returns the minimum element x which satisfies f(-∞) != f(x)
 * e.g.
 * i:    1 2 3 4 5 6 7 8 9
 * f(i): 0 0 0 0 0 0 1 1 1
 *                   ^
 *                   x
 */
template<class F>
int128 binary_search(F func) {
    int128 l = -1, r = 1;
    while (func(l) == func(r)) {
        l *= 2;
        r *= 2;
    }
    bool l_value = func(l);

    while (l != r) {
        int128 m = (l + r);
        if (m % 2 == 0) m /= 2;
        else m = (m - 1) / 2;
        if (func(m) != l_value) {
            r = m;
        } else {
            l = m + 1;
        }
    }
    return l;
}

int128 sqrt(int128 v) {
    return binary_search([v](int128 x) {
        if (x < 0) return false;
        if (x >= v) return true;
        return x * x >= v;
    });

}

vector<long long> best_time(long long t, long long a, long long b) {
    long long alpha = t + a;
    int128 B = 2 * alpha;
    int128 C = (int128) alpha * alpha - b;
    if (B * B - 4 * C < 0) {
        return {0};
    }
    int128 D = sqrt(B * B - 4 * C);

    return {0ll, (long long) ((-B + D) / 2), (long long) ((-B + D) / 2) + 1};
}

long long ceil(long long a, long long b) {
    return (a + b - 1) / b;
}

template<typename edge_t, typename cost_type = typename edge_t::cost_type>
std::vector<cost_type> dijkstra(const graph_t<edge_t> &g, int s) {
    std::vector<cost_type> d(g.size(), inf<cost_type>());
    d[s] = zero<cost_type>();
    using P = std::pair<cost_type, int>;
    std::priority_queue<P, std::vector<P>, std::greater<P>> que;
    que.push(P(zero<cost_type>(), s));
    while (!que.empty()) {
        cost_type dist = que.top().first;
        int v = que.top().second;
        que.pop();
        if (d[v] < dist) continue;
        for (const auto &e : g[v]) {
            for (auto k : best_time(dist, e.a, e.b)) {
                if (k < 0) continue;
//                while (k > 0) {
//                    long long cost = k + ceil(e.b, dist + e.a + k);
//                    long long cost2 = k-1 + ceil(e.b, dist + e.a + k-1);
//                    if( cost <= cost2 ){
//                        break;
//                    }
//                    --k;
//                }
//                while (true) {
//                    long long cost = k + ceil(e.b, dist + e.a + k);
//                    long long cost2 = k+1 + ceil(e.b, dist + e.a + k+1);
//                    if( cost <= cost2 ){
//                        break;
//                    }
//                    ++k;
//                }
                long long cost = k + ceil(e.b, dist + e.a + k);

                if (d[e.to] <= d[v] + cost) continue;
                d[e.to] = d[v] + cost;
                que.push(P(d[e.to], e.to));
            }
        }
    }
    return d;
}


template<typename Cost>
class WeightedEdge {
public:
    using cost_type = Cost;
    int to;
    cost_type cost;
    long long a, b;

    WeightedEdge(int, int t, cost_type c, long long a, long long b) : to(t), cost(c), a(a), b(b) { ; }
};

template<typename Cost> using WeightedGraph = graph_t<WeightedEdge<Cost>>;

template<typename Cost>
void add_edge(WeightedGraph<Cost> &g, int from, int to, Cost cost, long long a, long long b) {
    g[from].emplace_back(from, to, cost, a, b);
}

int main() {
    int N, M, S, G;
    cin >> N >> M >> S >> G;
    WeightedGraph<long long> g(N);

    for (int i = 0; i < M; i++) {
        long long u, v, a, b;
        cin >> u >> v >> a >> b;
        --u, --v;
        add_edge(g, u, v, 0ll, a, b);
        add_edge(g, v, u, 0ll, a, b);
    }
    --S, --G;

    auto ans = dijkstra(g, S)[G];
    if (ans != inf<long long>()) {
        cout << ans << endl;
    } else {
        cout << -1 << endl;
    }
}
accuracy: 1
time_ms: 430
memory_kb: 36024
final_rank: 11

code_snippet: #include "bits/stdc++.h"

#pragma warning(disable:4996)
using namespace std;
using ld = long double;
struct Edge {
	int src;
	int dst;
	long long int A;
	long long int B;
};
struct aa {
	int now;
	long long int cost;
};
bool operator <(const aa&l, const aa&r) {
	return l.cost>r.cost;
}
long long int ce(long long int a,long long  int b) {
	return (a-1)/b+1;
}
int main() {
	int N,M,S,G;cin>>N>>M>>S>>G;
	S--;G--;
	vector<vector<Edge>>g(N);

	for (int i = 0; i < M; ++i) {
		int a,b;
		long long int A,B;cin>>a>>b>>A>>B;a--;b--;
		g[a].push_back(Edge{ a,b,A,B });
		g[b].push_back(Edge{ b,a,A,B });
	}

	vector<long long int>memo(N,1e18);
	memo[S]=0;
	priority_queue<aa>que;
	que.push(aa{ S,0 });
	while (!que.empty()) {
		auto atop(que.top());
		que.pop();
		const int now=atop.now;
		const long long int now_cost=atop.cost;
		if(memo[now]!=now_cost)continue;
		for (auto e : g[now]) {
			int next=e.dst;
			long long int next_cost=now_cost;
			if (e.A >= 1e8) {
				next_cost=now_cost+ce(e.B,e.A+now_cost);
			}
			else {
				long long int needt=sqrt(e.B)-e.A;

				long long int this_cost=1e18;
				for (long long int stop_t = needt - 1; stop_t <= needt + 1; ++stop_t) {
					long long int at = max(stop_t, now_cost);
					{
						this_cost=min(this_cost,at+ce(e.B,e.A+at));
					}
				}
				next_cost=this_cost;
			}
			if (memo[next] > next_cost) {
				memo[next]=next_cost;
				que.push(aa{ next,next_cost });
			}
		}
	}
	if(memo[G]>7e17)memo[G]=-1;
	cout<<memo[G]<<endl;
	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 26648
final_rank: 7

code_snippet: #include "bits/stdc++.h"

#pragma warning(disable:4996)
using namespace std;
using ld = long double;
struct Edge {
	int src;
	int dst;
	long long int A;
	long long int B;
};
struct aa {
	int now;
	long long int cost;
};
bool operator <(const aa&l, const aa&r) {
	return l.cost>r.cost;
}
long long int ce(long long int a,long long  int b) {
	return (a-1)/b+1;
}
int main() {
	int N,M,S,G;cin>>N>>M>>S>>G;
	S--;G--;
	vector<vector<Edge>>g(N);

	for (int i = 0; i < M; ++i) {
		int a,b;
		int A,B;cin>>a>>b>>A>>B;a--;b--;
		g[a].push_back(Edge{ a,b,A,B });
		g[b].push_back(Edge{ b,a,A,B });
	}

	vector<long long int>memo(N,1e18);
	memo[S]=0;
	priority_queue<aa>que;
	que.push(aa{ S,0 });
	while (!que.empty()) {
		auto atop(que.top());
		que.pop();
		const int now=atop.now;
		const long long int now_cost=atop.cost;
		for (auto e : g[now]) {
			int next=e.dst;
			long long int next_cost=now_cost;
			if (e.A >= 1e8) {
				next_cost=now_cost+ce(e.B,e.A+now_cost);
			}
			else {
				long long int needt=sqrt(e.B)-e.A;

				long long int this_cost=1e18;
				for (long long int stop_t = needt - 2; stop_t <= needt + 2; ++stop_t) {
					long long int at = max(stop_t, now_cost);
					{
						this_cost=min(this_cost,at+ce(e.B,e.A+at));
					}
				}
				next_cost=this_cost;
			}
			if (memo[next] > next_cost) {
				memo[next]=next_cost;
				que.push(aa{ next,next_cost });
			}
		}
	}
	if(memo[G]>7e17)memo[G]=-1;
	cout<<memo[G]<<endl;
	return 0;
}
accuracy: 0.25396825396825395
time_ms: 10
memory_kb: 15912
final_rank: 20

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


#define REP(i, s) for (int i = 0; i < s; ++i)
#define ALL(v) (v.begin(), v.end())
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }



typedef pair<long long, long long> Par;
typedef pair<int, Par> Edge;
vector<vector<Edge> > G;

int N, M, s, g;

inline long long func(long long t, long long a, long long b) {
    return t + (b + t+a-1) / (t+a);
}
inline long long calc(long long K, long long a, long long b) {
    long long sb = (long long)(sqrt(b));
    long long start = max(0LL, sb - a - 2);
    long long res = func(K, a, b);
    for (long long t = start; t < start + 5; ++t) {
        if (t < K) continue;
        res = min(res, func(t, a, b));
    }
    return res;
}

int main() {
    cin >> N >> M >> s >> g;
    --s, --g;
    G.clear(); G.resize(N);
    for (int i = 0; i < M; ++i) {
        int u, v; cin >> u >> v; --u, --v;
        long long a, b; cin >> a >> b;
        G[u].push_back(Edge(v, Par(a, b)));
        G[v].push_back(Edge(u, Par(a, b)));
    }
    
    const long long INF = 1LL<<60;
    vector<long long> dp(N, INF);
    priority_queue<pair<long long,int>, vector<pair<long long,int> >, greater<pair<long long,int> > > que;
    que.push(make_pair(0, s));
    dp[s] = 0;
    while (!que.empty()) {
        auto cur = que.top(); que.pop();
        int v = cur.second;
        long long t = cur.first;
        if (dp[v] < t) continue;
        
        //cout << v << ": " << dp[v] << endl;
        
        for (auto e : G[v]) {
            int to = e.first;
            long long a = e.second.first;
            long long b = e.second.second;
            long long dist = calc(t, a, b);
            if (chmin(dp[to], dist)) que.push(make_pair(dist, to));
        }
    }
    if (dp[g] < INF) cout << dp[g] << endl;
    else cout << -1 << endl;
}
accuracy: 1
time_ms: 250
memory_kb: 26532
final_rank: 5

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


#define REP(i, s) for (int i = 0; i < s; ++i)
#define ALL(v) (v.begin(), v.end())
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }



typedef pair<long long, long long> Par;
typedef pair<int, Par> Edge;
vector<vector<Edge> > G;

int N, M, s, g;

inline long long func(long long t, long long a, long long b) {
    return t + (b + t+a-1) / (t+a);
}
inline long long calc(long long K, long long a, long long b) {
    long long sb = (long long)(sqrt(b));
    long long start = sb - 2;
    long long res = func(K, a, b);
    for (long long t = max(0LL, start); t < start + 5; ++t) {
        if (t < K) continue;
        res = min(res, func(t, a, b));
    }
    return res;
}

int main() {
    cin >> N >> M >> s >> g;
    --s, --g;
    G.clear(); G.resize(N);
    for (int i = 0; i < M; ++i) {
        int u, v; cin >> u >> v; --u, --v;
        long long a, b; cin >> a >> b;
        G[u].push_back(Edge(v, Par(a, b)));
        G[v].push_back(Edge(u, Par(a, b)));
    }
    
    const long long INF = 1LL<<60;
    vector<long long> dp(N, INF);
    priority_queue<pair<long long,int>, vector<pair<long long,int> >, greater<pair<long long,int> > > que;
    que.push(make_pair(0, s));
    dp[s] = 0;
    while (!que.empty()) {
        auto cur = que.top(); que.pop();
        int v = cur.second;
        long long t = cur.first;
        if (dp[v] < t) continue;
        
        //cout << v << ": " << dp[v] << endl;
        
        for (auto e : G[v]) {
            int to = e.first;
            long long a = e.second.first;
            long long b = e.second.second;
            long long dist = calc(t, a, b);
            if (chmin(dp[to], dist)) que.push(make_pair(dist, to));
        }
    }
    if (dp[g] < INF) cout << dp[g] << endl;
    else cout << -1 << endl;
}
accuracy: 0.38095238095238093
time_ms: 270
memory_kb: 19348
final_rank: 13

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
template<typename Func>
ll findMin(ll L, ll R, Func f) { //[L, R)
    ll lo = L - 1, hi = R - 1;
    while (lo + 1 != hi) {
        ll mi = (lo + hi) / 2;
        if (f(mi) <= f(mi + 1)) hi = mi;
        else lo = mi;
    }
    return hi;
}
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧  
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     
　　　　／　　　＼　 　 |　|     
　　　 /　　 /￣￣￣￣/　　|  
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  
　 　　　＼/＿＿＿＿/　（u　⊃  
---------------------------------------------------------------------------------------------------*/



int N, M, S, G, U[201010], V[201010]; ll A[201010], B[201010];
vector<pair<int,int>> E[201010];
ll dst[201010]; int vis[201010];
ll line[201010];
//---------------------------------------------------------------------------------------------------
ll a, b;
ll f(ll x) {
    return x + (b + x + a - 1) / (x + a);
}
double fd(double x) {
    return x + 1.0 * b / (x + 1.0 * a);
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> N >> M >> S >> G;
    S--; G--;
    rep(i, 0, M) {
        cin >> U[i] >> V[i] >> A[i] >> B[i];
        U[i]--; V[i]--;

        E[U[i]].push_back({ V[i], i });
        E[V[i]].push_back({ U[i], i });
    }

    rep(i, 0, N) dst[i] = infl;

    min_priority_queue<pair<ll, int>> que;
    que.push({0, S});
    dst[S] = 0;
    while (!que.empty()) {
        auto q = que.top(); que.pop();

        ll d = q.first;
        int cu = q.second;

        if (vis[cu]) continue;
        vis[cu] = 1;

        if (cu == G) {
            printf("%lld\n", dst[cu]);
            return;
        }

        fore(p, E[cu]) {
            int to = p.first;
            a = A[p.second];
            b = B[p.second];

            ll t = findMin(d, infl, fd);

            ll nd = min(f(t), f(t + 1));

            if (nd < dst[to]) {
                dst[to] = nd;
                que.push({ nd, to });
            }
        }
    }

    printf("-1\n");
}
accuracy: 1
time_ms: 220
memory_kb: 26684
final_rank: 4

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
template<typename Func>
double findMinReal(double L, double R, Func f) { //[L, R)
    double left = L, right = R;

    for (int loop = 0; loop < 101; ++loop) {
        if (f((left * 2 + right) / 3) <= f((left + right * 2) / 3)) {
            right = (left + right * 2) / 3;
        }
        else {
            left = (left * 2 + right) / 3;
        }
    }
    return (right + left) * 0.5;
}
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧  
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     
　　　　／　　　＼　 　 |　|     
　　　 /　　 /￣￣￣￣/　　|  
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  
　 　　　＼/＿＿＿＿/　（u　⊃  
---------------------------------------------------------------------------------------------------*/



int N, M, S, G, U[201010], V[201010]; ll A[201010], B[201010];
vector<pair<int,int>> E[201010];
ll dst[201010]; int vis[201010];
ll line[201010];
//---------------------------------------------------------------------------------------------------
ll a, b;
ll f(ll x) {
    return x + (b + x + a - 1) / (x + a);
}
double fr(double x) {
    return x + 1.0 * b / (x + a);
}
//---------------------------------------------------------------------------------------------------
ll getline(int i) {
    /*a = A[i]; b = B[i];
    double l = 0, h = 1e20;
    rep(i, 0, 200) {
        double m1 = l + (h - l) / 3, m2 = l + (h - l) / 3 * 2;
        double f1 = fr(m1), f2 = fr(m2);
        if (f1 > f2) l = m1; else h = m2;
    }
    return f((ll)l) < f((ll)l + 1) ? l : l + 1;*/

    a = A[i]; b = B[i];
    double t = findMinReal(0, infl, fr);

    ll res = t;
    ll mi = res;

    rep(d, -1, 2) if (0 <= res + d and f(res + d) < f(mi)) mi = res + d;
    return mi;
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> N >> M >> S >> G;
    S--; G--;
    rep(i, 0, M) {
        cin >> U[i] >> V[i] >> A[i] >> B[i];
        U[i]--; V[i]--;

        E[U[i]].push_back({ V[i], i });
        E[V[i]].push_back({ U[i], i });
        line[i] = getline(i);
    }

    rep(i, 0, N) dst[i] = infl;

    min_priority_queue<pair<ll, int>> que;
    que.push({0, S});
    dst[S] = 0;
    while (!que.empty()) {
        auto q = que.top(); que.pop();

        ll d = q.first;
        int cu = q.second;

        if (vis[cu]) continue;
        vis[cu] = 1;

        if (cu == G) {
            printf("%lld\n", dst[cu]);
            return;
        }

        fore(p, E[cu]) {
            int to = p.first;
            a = A[p.second];
            b = B[p.second];

            ll t;
            if (d < line[q.second]) t = line[p.second];
            else t = d;

            ll nd = f(t);

            if (nd < dst[to]) {
                dst[to] = nd;
                que.push({ nd, to });
            }
        }
    }
    printf("-1\n");
}
accuracy: 0.5238095238095238
time_ms: 400
memory_kb: 20888
final_rank: 12

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
#define double long double
template<typename Func>
double findMinReal(double L, double R, Func f) { //[L, R)
    double left = L, right = R;

    for (int loop = 0; loop < 201; ++loop) {
        if (f((left * 2 + right) / 3) <= f((left + right * 2) / 3)) {
            right = (left + right * 2) / 3;
        }
        else {
            left = (left * 2 + right) / 3;
        }
    }
    return (right + left) * 0.5;
}
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧  
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     
　　　　／　　　＼　 　 |　|     
　　　 /　　 /￣￣￣￣/　　|  
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  
　 　　　＼/＿＿＿＿/　（u　⊃  
---------------------------------------------------------------------------------------------------*/



int N, M, S, G, U[201010], V[201010]; ll A[201010], B[201010];
vector<pair<int,int>> E[201010];
ll dst[201010]; int vis[201010];
ll line[201010];
//---------------------------------------------------------------------------------------------------
ll a, b;
ll f(ll x) {
    return x + (b + x + a - 1) / (x + a);
}
double fr(double x) {
    return x + b / (x + a);
}
//---------------------------------------------------------------------------------------------------
ll getline(int i) {
    a = A[i]; b = B[i];
    double t = findMinReal(0, infl, fr);

    ll res = t;
    ll mi = res;

    rep(d, -1, 2) if (0 <= res + d and f(res + d) < f(mi)) mi = res + d;
    return mi;
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> N >> M >> S >> G;
    S--; G--;
    rep(i, 0, M) {
        cin >> U[i] >> V[i] >> A[i] >> B[i];
        U[i]--; V[i]--;

        E[U[i]].push_back({ V[i], i });
        E[V[i]].push_back({ U[i], i });
        line[i] = getline(i);
    }

    rep(i, 0, N) dst[i] = infl;

    min_priority_queue<pair<ll, int>> que;
    que.push({0, S});
    dst[S] = 0;
    while (!que.empty()) {
        auto q = que.top(); que.pop();

        ll d = q.first;
        int cu = q.second;

        if (vis[cu]) continue;
        vis[cu] = 1;

        if (cu == G) {
            printf("%lld\n", dst[cu]);
            return;
        }

        fore(p, E[cu]) {
            int to = p.first;
            a = A[p.second];
            b = B[p.second];

            ll t;
            if (d < line[q.second]) t = line[q.second];
            else t = d;

            ll nd = f(t);

            if (nd < dst[to]) {
                dst[to] = nd;
                que.push({ nd, to });
            }
        }
    }
    printf("-1\n");
}
accuracy: 0.31746031746031744
time_ms: 880
memory_kb: 20248
final_rank: 15

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
template<typename Func>
double findMinReal(double L, double R, Func f) { //[L, R)
    double left = L, right = R;

    for (int loop = 0; loop < 101; ++loop) {
        if (f((left * 2 + right) / 3) <= f((left + right * 2) / 3)) {
            right = (left + right * 2) / 3;
        }
        else {
            left = (left * 2 + right) / 3;
        }
    }
    return (right + left) * 0.5;
}
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧  
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     
　　　　／　　　＼　 　 |　|     
　　　 /　　 /￣￣￣￣/　　|  
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  
　 　　　＼/＿＿＿＿/　（u　⊃  
---------------------------------------------------------------------------------------------------*/



int N, M, S, G, U[201010], V[201010]; ll A[201010], B[201010];
vector<pair<int,int>> E[201010];
ll dst[201010]; int vis[201010];
ll line[201010];
//---------------------------------------------------------------------------------------------------
ll a, b;
ll f(ll x) {
    return x + (b + x + a - 1) / (x + a);
}
double fr(double x) {
    return x + b / (x + a);
}
//---------------------------------------------------------------------------------------------------
ll getline(int i) {
    a = A[i]; b = B[i];
    double t = findMinReal(0, infl, fr);

    ll res = t;
    ll mi = res;

    rep(d, -1, 2) if (0 <= res + d and f(res + d) < f(mi)) mi = res + d;
    return mi;
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> N >> M >> S >> G;
    S--; G--;
    rep(i, 0, M) {
        cin >> U[i] >> V[i] >> A[i] >> B[i];
        U[i]--; V[i]--;

        E[U[i]].push_back({ V[i], i });
        E[V[i]].push_back({ U[i], i });
        line[i] = getline(i);
    }

    rep(i, 0, N) dst[i] = infl;

    min_priority_queue<pair<ll, int>> que;
    que.push({0, S});
    dst[S] = 0;
    while (!que.empty()) {
        auto q = que.top(); que.pop();

        ll d = q.first;
        int cu = q.second;

        if (vis[cu]) continue;
        vis[cu] = 1;

        if (cu == G) {
            printf("%lld\n", dst[cu]);
            return;
        }

        fore(p, E[cu]) {
            int to = p.first;
            a = A[p.second];
            b = B[p.second];

            ll t;
            if (d < line[q.second]) t = line[q.second];
            else t = d;

            ll nd = f(t);

            if (nd < dst[to]) {
                dst[to] = nd;
                que.push({ nd, to });
            }
        }
    }
    printf("-1\n");
}
accuracy: 0.31746031746031744
time_ms: 400
memory_kb: 20180
final_rank: 14