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

Solution in C++14 (judge verdict: Time Limit Exceeded)

#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;
		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;
}