Problem:
Problem E: Tangled Cables
Problem
とある会社のネットワーク上には$n$台のコンピュータと、それらをつなぐ$m$本の通信ケーブルがある。コンピュータは$0$から$n - 1$までの識別子で区別され、通信ケーブルもまた$0$から$m - 1$までの識別子をもつ。
現在この会社にある任意の異なる2台のコンピュータは、いくつかの通信ケーブルを介して相互に通信することができるが、通信経路がただ一つに定まるとは限らない。
このネットワークには、通信ケーブルが多すぎて絡まってしまうという問題がある。そこであなたは、任意の通信について通信経路がただ一つになるようにいくつかの通信ケーブルを取り除くことにした。
通信ケーブル$i$はコンピュータ$a_i$と$b_i$を双方向につなぎ、その長さは$c_i$である。また、あなたが通信ケーブル$i$を取り除く際にかかる労力は$d_i$である。
作業を始める前に、あなたは取り除く通信ケーブルの長さの和に対する、作業を終えるまでにかかる労力の和の比を「おっくう感」とし、最小のおっくう感を見積もることにした。
ただし、一つも取り除けない場合のおっくう感は$0$である。
Input
入力は以下の形式で与えられる。
$n$ $m$
$a_1$ $b_1$ $c_1$ $d_1$
$a_2$ $b_2$ $c_2$ $d_2$
...
$a_m$ $b_m$ $c_m$ $d_m$
入力はすべて整数で与えられる。
1行目にはコンピュータの数$n$と通信ケーブルの数$m$が空白区切りで与えられる。
2行目以降の$m$行には、通信ケーブルの情報が空白区切りで与えられる。$i$番目の通信ケーブルの情報は、通信ケーブル$i$の情報を表す。
Constraints
入力は以下の条件を満たす。
$2 \leq n \leq 10^4$
$n-1 \leq m \leq min(\frac{n \times (n - 1)}{2}, 10^4)$
$0 \leq a_i, b_i \leq n - 1 (a_i ≠ b_i)$
$1 \leq c_i \leq 10^6$
$0 \leq d_i \leq 10^6$
Output
おっくう感の最小値を実数で1行に出力する。ただし、$10^{-5}$を超える誤差を含んではならない。
Sample Input 1
4 5
0 2 22 13
0 3 15 25
1 2 3 3
1 3 28 5
2 3 5 22
Sample Output 1
0.36000
通信ケーブル$0$と通信ケーブル$3$を取り除くと、おっくう感は$(\frac{13 + 5}{22 + 28}) = 0.36$となり、これがおっくう感の最小値となる。
Sample Input 2
5 6
0 1 22 33
0 2 43 11
0 3 92 10
1 3 50 12
2 3 88 2
3 4 58 89
Sample Output 2
0.06667
Sample Input 3
2 1
0 1 1 1
Sample Output 3
0

Submitted solutions:

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

#define FOR(i,s,t) for(int i = s ; i < t ; i++)
using LL = long long; using ll = LL;
using PII = pair<int, int>; using pii = PII;
using PLL = pair<LL, LL>; using pll = PLL;
const int INF = 1e9;

struct UnionFind {
	vector<int> data;
	UnionFind(int n) { data.assign(n, -1); }
	bool unite(int x, int y) {
		x = root(x); y = root(y);
		if (x != y) {
			if (data[y] < data[x]) swap(x, y);
			data[x] += data[y]; data[y] = x;
		}
		return x != y;
	}
	bool same(int x, int y) {
		return root(x) == root(y);
	}
	int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
	int size(int x) { return -data[root(x)]; }
};
#define SZ(a) (int)a.size()

using vc = const vector<int>&;
bool f(vc a, vc b, vc c, vc d, double X, int N) {
	using tp = tuple<double, int, int>;
	vector<tp>edge;
	FOR(i, 0, SZ(a)) {
		edge.push_back(tp((double)d[i] - X * (double)c[i],a[i], b[i]));
	}
	sort(edge.rbegin(), edge.rend());
	double sum = 0.0;
	UnionFind uf(N);
	FOR(i, 0, SZ(a)) {
		int A, B; double D;
		tie(D, A, B) = edge[i];
		if (!uf.same(A, B)) {
			uf.unite(A, B);
		}
		else {
			sum += D;
		}
	}
	return sum <= 0.0;
}



void solve() {
	int N, M;
	cin >> N >> M;
	vector<int> a(M), b(M), c(M), d(M);
	FOR(i, 0, M) {
		cin >> a[i] >> b[i] >> c[i] >> d[i];
	}
	double L = 0; double R = INF;
	FOR(i, 0, 100) {
		double mid = (L + R) / 2.0;
		if (f(a, b, c, d, mid, N)) {
			R = mid;
		}
		else {
			L = mid;
		}
	}
	cout << fixed << setprecision(10) << R << endl;

}

int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	solve();

	return 0;

}
accuracy: 1
time_ms: 60
memory_kb: 3876
final_rank: 10

code_snippet: #include <iostream>

#include <vector>

#include <algorithm>

#include <iomanip>

using namespace std;

struct p {
    int v1, v2;
    long long c, d;
};

struct pp {
    int v1, v2;
    double w;
};

bool compp(pp a, pp b) {
    return (a.w < b.w);
}

int predd(int v, vector <int>& pred) {
    while (pred[v] != -1) {
        v = pred[v];
    }
    return v;
}

bool check(int n, int m, vector <p> rebs, double mid, double cc, double dd) {
    vector <pp> new_rebs(m);
    for (int i = 0; i < m; i++) {
        new_rebs[i].v1 = rebs[i].v1;
        new_rebs[i].v2 = rebs[i].v2;
        new_rebs[i].w = mid * rebs[i].c - rebs[i].d;
    }
    sort(new_rebs.begin(), new_rebs.end(), compp);
    double ans = 0;
    vector <int> pred(n, -1);
    vector <int> sizes(n, 1);
    for (int i = 0; i < m; i++) {
        int p1 = predd(new_rebs[i].v1, pred), p2 = predd(new_rebs[i].v2, pred);
        if (p1 != p2) {
            ans += new_rebs[i].w;
            if (sizes[p1] < sizes[p2]) {
                sizes[p2] += sizes[p1];
                pred[p1] = p2;
            } else {
                sizes[p1] += sizes[p2];
                pred[p2] = p1;
            }
        }
    }
    return (ans <= mid * cc - dd);
}

int main() {
    int n, m;
    cin >> n >> m;
    if (m == n - 1) {
        cout << 0;
        return 0;
    }
    vector <p> rebs(m);
    double cc = 0, dd = 0;
    for (int i = 0; i < m; i++) {
        cin >> rebs[i].v1 >> rebs[i].v2 >> rebs[i].c >> rebs[i].d;
        cc += rebs[i].c;
        dd += rebs[i].d;
    }
    double ll = 0, rr = 1000057;
    for (int w = 0; w < 70; w++) {
        double mid = (ll + rr) / 2;
        if (check(n, m, rebs, mid, cc, dd)) {
            rr = mid;
        } else {
            ll = mid;
        }
    }
    cout << setprecision(10) << rr;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3940
final_rank: 13

code_snippet: #include <iostream>

#include <vector>

#include <algorithm>

#include <iomanip>

using namespace std;

struct p {
    int v1, v2;
    long long c, d;
};

struct pp {
    int v1, v2;
    double w;
};

bool compp(pp a, pp b) {
    return (a.w < b.w);
}

int predd(int v, vector <int>& pred) {
    while (pred[v] != -1) {
        v = pred[v];
    }
    return v;
}

bool check(int n, int m, vector <p> rebs, double mid, double cc, double dd) {
    vector <pp> new_rebs(m);
    for (int i = 0; i < m; i++) {
        new_rebs[i].v1 = rebs[i].v1;
        new_rebs[i].v2 = rebs[i].v2;
        new_rebs[i].w = mid * rebs[i].c - rebs[i].d;
    }
    sort(new_rebs.begin(), new_rebs.end(), compp);
    double ans = 0;
    vector <int> pred(n, -1);
    vector <int> sizes(n, 1);
    for (int i = 0; i < m; i++) {
        int p1 = predd(new_rebs[i].v1, pred), p2 = predd(new_rebs[i].v2, pred);
        if (p1 != p2) {
            ans += new_rebs[i].w;
            if (sizes[p1] < sizes[p2]) {
                sizes[p2] += sizes[p1];
                pred[p1] = p2;
            } else {
                sizes[p1] += sizes[p2];
                pred[p2] = p1;
            }
        }
    }
    return (ans <= mid * cc - dd);
}

int main() {
    int n, m;
    cin >> n >> m;
    if (m == n - 1) {
        cout << 0;
        return 0;
    }
    vector <p> rebs(m);
    double cc = 0, dd = 0;
    for (int i = 0; i < m; i++) {
        cin >> rebs[i].v1 >> rebs[i].v2 >> rebs[i].c >> rebs[i].d;
        cc += rebs[i].c;
        dd += rebs[i].d;
    }
    double ll = 0, rr = 1000057;
    for (int w = 0; w < 70; w++) {
        double mid = (ll + rr) / 2;
        if (check(n, m, rebs, mid, cc, dd)) {
            rr = mid;
        } else {
            ll = mid;
        }
    }
    if (0 && rr < 0.000000001) {
        rr = 0;
    }
    cout << setprecision(10) << rr;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3920
final_rank: 11

code_snippet: #include <iostream>

#include <vector>

#include <algorithm>

#include <iomanip>

using namespace std;

struct p {
    int v1, v2;
    long long c, d;
};

struct pp {
    int v1, v2;
    double w;
};

bool compp(pp a, pp b) {
    return (a.w < b.w);
}

int predd(int v, vector <int>& pred) {
    while (pred[v] != -1) {
        v = pred[v];
    }
    return v;
}

bool check(int n, int m, vector <p> rebs, double mid, double cc, double dd) {
    vector <pp> new_rebs(m);
    for (int i = 0; i < m; i++) {
        new_rebs[i].v1 = rebs[i].v1;
        new_rebs[i].v2 = rebs[i].v2;
        new_rebs[i].w = mid * rebs[i].c - rebs[i].d;
    }
    sort(new_rebs.begin(), new_rebs.end(), compp);
    double ans = 0;
    vector <int> pred(n, -1);
    vector <int> sizes(n, 1);
    for (int i = 0; i < m; i++) {
        int p1 = predd(new_rebs[i].v1, pred), p2 = predd(new_rebs[i].v2, pred);
        if (p1 != p2) {
            ans += new_rebs[i].w;
            if (sizes[p1] < sizes[p2]) {
                sizes[p2] += sizes[p1];
                pred[p1] = p2;
            } else {
                sizes[p1] += sizes[p2];
                pred[p2] = p1;
            }
        }
    }
    return (ans <= mid * cc - dd);
}

int main() {
    int n, m;
    cin >> n >> m;
    if (m == n - 1) {
        cout << 0;
        return 0;
    }
    vector <p> rebs(m);
    double cc = 0, dd = 0;
    for (int i = 0; i < m; i++) {
        cin >> rebs[i].v1 >> rebs[i].v2 >> rebs[i].c >> rebs[i].d;
        cc += rebs[i].c;
        dd += rebs[i].d;
    }
    double ll = 0, rr = 1000057;
    for (int w = 0; w < 70; w++) {
        double mid = (ll + rr) / 2;
        if (check(n, m, rebs, mid, cc, dd)) {
            rr = mid;
        } else {
            ll = mid;
        }
    }
    if (rr < 0.000000001) {
        rr = 0;
    }
    cout << setprecision(10) << rr;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3944
final_rank: 14

code_snippet: // AOJ #3004 Tangled Cables
// 2025.3.24

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

struct Edge { int a, b; ll c, d; };

int findp(vector<int>& p, int x) {
    return (p[x]==x ? x : p[x] = findp(p, p[x]));
}

void unionp(vector<int>& p, vector<int>& r, int x, int y) {
    x = findp(p, x); y = findp(p, y);
    if(x==y)return;
    if(r[x]<r[y]) swap(x,y);
    p[y]=x;
    if(r[x]==r[y]) r[x]++;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    vector<Edge> E(m);
    ll totC = 0, totD = 0;
    for (int i = 0; i < m; i++){
        cin >> E[i].a >> E[i].b >> E[i].c >> E[i].d;
        totC += E[i].c;
        totD += E[i].d;
    }
    if(m == n-1){
        cout << fixed << setprecision(5) << 0.0 << endl;
        return 0;
    }

    double lo = 0.0, hi = (double)totD / totC;
    for (int iter = 0; iter < 60; iter++){
        double mid = (lo+hi)/2.0;
        vector<pair<double, Edge>> ve;
        double sumAll = 0.0;
        for(auto &e : E){
            double w = e.d - mid * e.c;
            ve.push_back({w, e});
            sumAll += w;
        }
        sort(ve.begin(), ve.end(), [](auto &l, auto &r){
            return l.first > r.first;
        });
        vector<int> p(n), r(n,0);
        for(int i=0;i<n;i++) p[i]=i;
        double sumT = 0.0;
        int cnt = 0;
        for(auto &pr : ve){
            int a = pr.second.a, b = pr.second.b;
            if(findp(p,a) != findp(p,b)){
                unionp(p, r, a, b);
                sumT += pr.first;
                cnt++;
                if(cnt == n-1) break;
            }
        }
        if(sumAll - sumT <= 0) hi = mid;
        else lo = mid;
    }
    cout << fixed << setprecision(5) << hi << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 4120
final_rank: 16

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

struct UF{
  int par[10000];
  int size[10000];
  void init(int n){
    for(int i=0;i<n;i++){
      par[i]=i;
      size[i]=1;
    }
  }
  int find(int x){
    if(x==par[x])return x;
    return par[x]=find(par[x]);
  }
  void unite(int x,int y){
    x=find(x),y=find(y);
    if(x==y)return;
    if(size[x]<size[y])swap(x,y);
    par[y]=x;
    size[x]+=size[y];
  }
  bool same(int x,int y){
    return ( find(x)==find(y) );
  }
};

struct edge{
  int from;
  int to;
  int A;
  int B;
};

int N,M;
vector<edge> edges;

bool check(double K){
  typedef pair<double,int> P;
  vector<P> tmp;

  for(int i=0;i<(int)edges.size();i++){
    edge e=edges[i];

    tmp.push_back(  P( (double)e.B-(double)e.A*K , i ) );
  }
  sort(tmp.begin(),tmp.end());
  reverse(tmp.begin(),tmp.end());
  UF uf;
  uf.init(N);
  
  double sum=0;
  for(int i=0;i<(int)tmp.size();i++){
    edge e=edges[ tmp[i].second ];
    
    if( uf.same(e.from,e.to ) ){
      sum+=tmp[i].first;
    }else{
      uf.unite(e.from,e.to);
    }
  }

  if(uf.size[ uf.find(0) ]!=N)return false;
  return ( sum<=0.0 );
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    int from,to,A,B;
    cin>>from>>to>>A>>B;
    edges.push_back( (edge){from,to,A,B} );
  }

  double left=0, right=1e7, mid;
  for(int i=0;i<100;i++){
    mid=(left+right)/2.0;
    if( check(mid) )right=mid;
    else left=mid;
  }
  printf("%.10f\n",left);
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3840
final_rank: 9

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define INF 1001000100010001000
#define MOD 1000000007
#define EPS 1e-10
#define int long long
#define rep(i, N) for (int i = 0; i < N; i++)
#define Rep(i, N) for (int i = 1; i < N; i++)
#define For(i, a, b) for (int i = (a); i < (b); i++)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define i_i pair<int, int>
#define vi vector<int>
#define vvi vector<vi >
#define vb vector<bool>
#define vvb vector<vb >
#define vp vector< i_i >
#define all(a) (a).begin(), (a).end()
#define Int(x) int x; scanf("%lld", &x);
#define int2(x, y) int x, y; scanf("%lld %lld", &x, &y);
#define UF uftree
 
//int dxy[5] = {0, 1, 0, -1, 0};
// assign

class uftree 
{
    public:
        int size;
        vector<int> par, rank;
        uftree(int n) : size(n), par(n), rank(n) {
            for (int i = 0; i < size; i++) {
                par[i] =  i;
                rank[i] = 0;
            }
        }
        int find(int x) {
            if (par[x] == x) {
                return x;
            } else {
                return par[x] = find(par[x]);
            }
        }
        void unite(int x, int y) {
            x = find(x);
            y = find(y);
            if (x == y) {
                return ;
            }

            if (rank[x] < rank[y]) {
                par[x] = y;
            } else {
                par[y] = x;
                if (rank[x] == rank[y]) {
                    rank[x]++;
                }
            }
        }
        bool same(int x, int y) {
            return find(x) == find(y);
        }
};

struct edge {
    int from, to, len, cost;
};
int n, m;
struct edge data[10000];
pair<double, int> funami[10000];

void make(double x);
bool solve();

signed main()
{
    cin >> n >> m;
    rep(i, m) {
        cin >> data[i].from >> data[i].to >> 
            data[i].len >> data[i].cost;
    }

    double l = 0.0, r = 1.0;
    while (r - l > 0.000001) {
        double ans = (r + l) / 2;
        make(ans);
        //cout << ans << " ";
        if (solve()) {
            r = ans;
        } else {
            l = ans;
        }
    }
    printf("%.10lf\n", l);

    return 0;
}

bool solve()
{
    UF kyoko(n);
    double sum = 0.0;
    for (int i = m -1; i >= 0; i--) {
        if (kyoko.same( data[funami[i].second].from, 
                    data[funami[i].second].to)) {
            sum += funami[i].first;
        } else {
            kyoko.unite(data[funami[i].second].from,
                    data[funami[i].second].to);
        }
    }
    //cout << sum << endl;
    if (sum > 0) return false;
    else return true;
}


void make(double x)
{
    for (int i = 0; i < m; i++) {
        funami[i].first = data[i].cost - data[i].len * x;
        funami[i].second = i;
    }
    sort(funami, funami + m);
}
accuracy: 1
time_ms: 10
memory_kb: 4128
final_rank: 15

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<utility>
#include<set>
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
typedef long double ld;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define stop char nyaa;cin>>nyaa;

struct SegT {
private:
	int n; vector<vec> node;
	vector<vec> lazy;
	vec e;
public:
	SegT(vector<int> v) {
		int sz = v.size();
		n = 1;
		while (n < sz)n <<= 1;
		vec t(10, 0);
		node.resize(2 * n - 1, t);
		e.resize(10);
		rep(i, 10) {
			e[i] = i;
		}
		lazy.resize(2 * n - 1, e);
		rep(i, sz) {
			node[i + sz - 1][v[i]]++;
		}
		per(i, sz - 1) {
			node[i] = f(node[2 * i + 1], node[2 * i + 2]);
		}
	}
	vec f(vec &a, vec &b) {
		vec ret(10,0);
		rep(i, 10) {
			ret[i] = a[i] + b[i];
		}
		return ret;
	}
	//lazy & lazy
	vec g(vec &a, vec &b) {
		vec ret(10);
		rep(i, n) {
			ret[i] = a[b[i]];
		}
		return ret;
	}
	void eval(int k, int l, int r) {
		vec nex(10, 0);
		rep(i, 10) {
			nex[lazy[k][i]] += node[k][i];
		}
		node[k] = nex;
		if (r - l > 1) {

		}
	}
};

struct uf {
private:
	vector<int> par, ran;
public:
	uf(int n) {
		par.resize(n, 0);
		ran.resize(n, 0);
		rep(i, n) {
			par[i] = i;
		}
	}
	int find(int x) {
		if (par[x] == x)return x;
		else return par[x] = find(par[x]);
	}
	void unite(int x, int y) {
		x = find(x), y = find(y);
		if (x == y)return;
		if (ran[x] < ran[y]) {
			par[x] = y;
		}
		else {
			par[y] = x;
			if (ran[x] == ran[y])ran[x]++;
		}
	}
	bool same(int x, int y) {
		return find(x) == find(y);
	}
};

int n, m;

struct edge {
	int a, b; ld cost, dist;
};
vector<edge> v;

void solve() {
	cin >> n >> m;
	v.resize(m);
	rep(i, m) {
		int a, b;ld c, d; cin >> a >> b >> c >> d;
		v[i] = { a,b,c,d };

	}
	ld le = 0, ri = 2000000;
	rep (aa,50) {
		ld mid = (le + ri) / 2.0;
		vector<pair<ld, P>> a;
		uf u(n);
		rep(i, m) {
			ld score = v[i].dist - v[i].cost*mid;
			a.push_back({ score,{v[i].a,v[i].b} });
		}
		sort(a.begin(), a.end(),greater<pair<ld,P>>());
		ld sum = 0;
		rep(i, m) {
			int l = a[i].second.first, r = a[i].second.second;
			sum += a[i].first;
			if (!u.same(l, r)) {
				u.unite(l, r);
				sum -= a[i].first;
			}
		}
		if (sum <= 0) {
			ri = mid;
		}
		else {
			le = mid;
		}
	}
	cout << ri << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(6);
	solve();
	//stop
		return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4252
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

struct UF{
    int n;
    //正だったらその頂点の親,負だったら根で連結成分の個数
    vector<int> d;
    UF() {}
    UF(int N):n(N), d(N,-1){}
    int root(int v){
        if(d[v]<0) return v;
        return d[v]=root(d[v]);
    }
    bool unite(int X,int Y){
        X=root(X); Y=root(Y);
        if(X==Y) return false;
        if(size(X) < size(Y)) swap(X,Y);
        d[X]+=d[Y];
        d[Y]=X;
        return true;
    }
    int size(int v){ return -d[root(v)]; }
    bool same(int X,int Y){ return root(X)==root(Y); }
};

using pd = pair<double,int>;

int main(){
    int n,m;
    scanf(" %d %d", &n, &m);
    vector<int> a(m),b(m),c(m),d(m);
    rep(i,m) scanf(" %d %d %d %d", &a[i], &b[i], &c[i], &d[i]);

    auto check = [&](double x){
        vector<pd> v(m);
        rep(i,m) v[i] = {x*c[i]-d[i], i};

        sort(all(v));

        UF uf(n);
        double tmp = 0;
        rep(i,m){
            int vi = v[i].se;
            int p = a[vi], q = b[vi];
            if(uf.same(p,q)) tmp += v[i].fi;
            else uf.unite(p,q);
        }

        return tmp >= 0;
    };

    double l=0, r=1e11;
    rep(loop,70){
        double mid = (l+r)/2;
        if(check(mid)) r = mid;
        else l = mid;
    }
    printf("%.10f\n", r);
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3480
final_rank: 3

code_snippet: //#error "tsurai"

#include <cstdio>
#include <cstdint>
#include <algorithm>
#include <queue>
#include <functional>

template <class T>
using pqueue=std::priority_queue<T, std::vector<T>, std::less<T>>;

struct Edge {
  size_t a, b;
  intmax_t c, d;
  Edge(size_t a, size_t b, intmax_t c, intmax_t d): a(a), b(b), c(c), d(d) {}
};

using Graph=std::vector<std::vector<Edge>>;

bool ok(const Graph &g, double p) {
  std::vector<bool> visited(g.size());

  double S=0;
  for (size_t i=0; i<g.size(); ++i)
    for (const auto &e: g[i]) {
      S += e.d - e.c*p;
    }
  S *= 0.5;
  //fprintf(stderr, "p: %.12f, S: %.16f\n", p, S);

  pqueue<std::pair<double, size_t>> q;
  q.emplace(0, 0);
  //visited[0] = true;
  double res=0;
  while (!q.empty()) {
    double w=q.top().first;
    size_t v=q.top().second;
    q.pop();
    if (visited[v]) continue;
    visited[v] = true;
    res += w;
    //fprintf(stderr, "w: %.12f\n", w);

    for (const auto &e: g[v]) {
      if (visited[e.b]) continue;
      double nw=e.d-p*e.c;
      q.emplace(nw, e.b);
    }
  }

  return res >= S;
}

int main() {
  size_t n, m;
  scanf("%zu %zu", &n, &m);

  if (n == m+1)
    return !printf("0\n");

  Graph g(n);
  for (size_t i=0; i<m; ++i) {
    size_t a, b;
    intmax_t c, d;
    scanf("%zu %zu %jd %jd", &a, &b, &c, &d);

    g[a].emplace_back(a, b, c, d);
    g[b].emplace_back(b, a, c, d);
  }

  double lb=0, ub=1e12;
  for (int i=0; i<200; ++i) {
    double p=0.5*(lb+ub);
    (ok(g, p)? ub:lb) = p;
  }
  printf("%.12f\n", lb);
}
accuracy: 1
time_ms: 210
memory_kb: 3708
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using LL = long long;

struct edge {
	int a, b;
	LL len;
	LL rou;
	double cost;
	bool operator<(const edge&o)const {
		return cost < o.cost;
	}
};

LL n, m;
vector<edge>vec;

struct ufind {
	vector<int>par, val;
	ufind(int n) {
		par.resize(n);
		val.resize(n);
		for (int i = 0; i < n; ++i) {
			par[i] = i;
		}
	}
	int getpar(int x) {
		if (par[x] == x)return x;
		return par[x] = getpar(par[x]);
	}
	bool same(int u, int v) {
		return getpar(u) == getpar(v);
	}
	void unite(int u, int v) {
		u = getpar(u);
		v = getpar(v);
		if (u == v)return;
		if (val[u] < val[v]) {
			par[u] = v;
		}
		else if (val[u] > val[v]) {
			par[v] = u;
		}
		else {
			par[u] = v;
			++val[v];
		}
	}
};

int main(void)
{
	cin >> n >> m;
	cout.precision(10);
	if (m == n - 1) {
		cout << 0. << endl;
		return 0;
	}
	for (int i = 0; i < m; ++i) {
		int a, b, c, d;
		cin >> a >> b >> c >> d;
		vec.push_back({ a,b,c,d });
	}
	double lo = 0, hi = 1e7;
	for (int loopcount = 0; loopcount < 100; ++loopcount) {
		double mid = (lo + hi) / 2;
		double total = 0.;
		for (auto& e : vec) {
			e.cost = e.rou - mid * e.len;
			total += e.cost;
		}
		sort(vec.rbegin(), vec.rend());
		double sum = 0;
		ufind uf(n);
		for (edge&e : vec) {
			if (!uf.same(e.a, e.b)) {
				uf.unite(e.a, e.b);
				sum += e.cost;
			}
		}
		double ans = total - sum;
		if (ans <= 0) {
			hi = mid;
		}
		else {
			lo = mid;
		}
	}
	cout << lo << endl;
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3552
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#define M 10005
using namespace std;
typedef pair<int,int> P;
typedef pair<double,P> P1;

#define rank Asdfiasofsad
class UF{
public:
  int V;
  vector<int> par,rank;
  UF(){}
  UF(int V):V(V),par(V),rank(V,0){for(int i=0;i<V;i++)par[i]=i;}
  
  int find(int x){
    assert(x < V);
    if(par[x]==x)return x;
    return par[x]=find(par[x]);
  }
  
  void unite(int x,int y){
    x=find(x), y=find(y);
    if(x==y)return;
    if(rank[x]<rank[y])par[x]=y;
    else{
      par[y]=x;
      if(rank[x]==rank[y])rank[x]++;
    }
  }
  
  bool same(int x,int y){return find(x)==find(y);}
};

int n, m, a[M], b[M], c[M], d[M], ans;

bool check(double X){
  
  UF uf=UF(n);
  
  priority_queue<P1> q;
  
  double S=0;
  
  for(int i=0;i<m;i++){
    q.push(P1(d[i]-X*c[i],P(a[i],b[i])));
    S+=d[i]-X*c[i];
  }
  
  double sum=0;
  
  while(!q.empty()){
    
    P1 t=q.top(); q.pop();
    
    int A=t.second.first, B=t.second.second;
    
    if(uf.same(A,B)) continue;
    
    sum+=t.first;
    
    uf.unite(A,B);
  }
  
  return S-sum<=(1e-8);
}

void solve(){
  
  double l=0, r=100000005;
  int cnt=100;
  
  while(cnt--){
    
    double Mid=(l+r)/2.0;
    
    if(!check(Mid)) l=Mid;
    else r=Mid;
    
  }
  
  printf("%.8f\n", l);
}

int main(){
  
  cin>>n>>m;
  
  for(int i=0;i<m;i++) cin>>a[i]>>b[i]>>c[i]>>d[i];
  
  solve();
  
  return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3548
final_rank: 8

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Edge{
	bool operator<(const struct Edge &arg) const{
		return diff < arg.diff;
	}
	int from,to;
	double length,cost,diff;
};


int N,M;
int boss[10000],height[10000];
Edge edge[10000];

int get_boss(int id){
	if(boss[id] == id)return id;
	else{
		return boss[id] = get_boss(boss[id]);
	}
}

int IS_SAME(int x,int y){
	return get_boss(x) == get_boss(y);
}

void unite(int x,int y){
	int boss_x = get_boss(x);
	int boss_y = get_boss(y);

	if(boss_x == boss_y)return;

	if(height[x] > height[y]){

		boss[boss_y] = boss_x;

	}else if(height[x] < height[y]){

		boss[boss_x] = boss_y;

	}else{ //height[x] == height[y]

		boss[boss_y] = boss_x;
		height[x]++;
	}
}

void init(){

	for(int i = 0; i < N; i++){
		boss[i] = i;
		height[i] = i;
	}
}

bool check(double per_length){

	init();

	for(int i = 0; i < M; i++){
		edge[i].diff = edge[i].length*per_length-edge[i].cost;
	}

	sort(edge,edge+M);

	double sum = 0.0;

	for(int i = 0; i < M; i++){
		if(!IS_SAME(edge[i].from,edge[i].to)){
			unite(edge[i].from,edge[i].to);
		}else{
			sum += edge[i].diff;
		}
	}

	return sum >= 0.0;
}

int main(){

	scanf("%d %d",&N,&M);

	for(int i = 0; i < M; i++){
		scanf("%d %d %lf %lf",&edge[i].from,&edge[i].to,&edge[i].length,&edge[i].cost);
	}

	double left = 0.0,right = 9999999.0,m = (left+right)/2;

	for(int loop = 0; loop < 100; loop++){
		if(check(m)){
			right = m-EPS;
		}else{
			left = m+EPS;
		}
		m = (left+right)/2;
	}

	printf("%.10lf\n",m);

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3644
final_rank: 6

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;


struct UnionFind {
	vector<int> data;
	UnionFind(int size) : data(size, -1) { }
	bool unionSet(int x, int y) {
		x = root(x); y = root(y);
		if (x != y) {
			if (data[y] < data[x]) swap(x, y);
			data[x] += data[y]; data[y] = x;
		}
		return x != y;
	}
	int root(int x) {
		return data[x] < 0 ? x : data[x] = root(data[x]);
	}
	int size(int x) {
		return -data[root(x)];
	}
};

struct Edge {
	int a;
	int b;
	ld len;
	ld cost;
};

double len_sum = 0, cost_sum = 0;
bool check(int N,ld ratio, vector<Edge>&es) {
	sort(es.begin(), es.end(), [&](
		const Edge&l, const Edge&r) {
		return l.cost - l.len*ratio>
			r.cost - r.len*ratio;
	});
	UnionFind uf(N);
	double len_use = 0;
	double cost_use = 0;
	for (int i = 0; i < es.size(); ++i) {
		if (uf.root(es[i].a) != uf.root(es[i].b)) {
			len_use += es[i].len;
			cost_use += es[i].cost;
			uf.unionSet(es[i].a, es[i].b);
		}
	}
	return (cost_sum - cost_use) / (len_sum - len_use) > ratio;
}
int main() {
	int N, M; cin >> N >> M;
	vector<Edge>es;
	for (int i = 0; i < M; ++i) {
		int a, b;ld c, d; cin >> a >> b >> c >> d;
		es.push_back(Edge{ a,b,c,d });
		len_sum += c;
		cost_sum += d;
	}
	if (N == M + 1)cout << 0 << endl;
	else {
		ld amin = -7;
		ld amax = 7;
		int k = 50;
		while (k--) {
			ld amid = (amin + amax) / 2;
			if (check(N, powl(10, amid), es)) {
				amin = amid;
			}
			else {
				amax = amid;
			}
		}
		cout <<fixed<<setprecision(10)<< powl(10, amin) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3976
final_rank: 12

code_snippet: #include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <functional>
#include <iostream>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct edge{
	int f,t;
	int c,d;
	double cost;
	edge(){}
	bool operator<(const edge &e)const{
		return cost<e.cost;
	}
};

int n,m;
edge e[100001];
int par[10001],rank[10001];

int find(int x){
	if(par[x]==x){
		return x;
	}else{
		return par[x]=find(par[x]);
	}
}

void unite(int x,int y){
	x=find(x);
	y=find(y);
	if(x==y)return;
	if(rank[x]<rank[y]){
		par[x]=y;
	}else{
		par[y]=x;
		if(rank[x]==rank[y])rank[x]++;
	}
}

bool same(int x,int y){
	return find(x)==find(y);
}

bool C(double x){
	for(int i=0;i<m;i++){
		e[i].cost=(double)e[i].c*x-e[i].d;
	}
	sort(e,e+m);
	double res=0.0;
	for(int i=0;i<n;i++){
		par[i]=i;
		rank[i]=0;
	}
	for(int i=0;i<m;i++){
		if(!same(e[i].f,e[i].t)){
			unite(e[i].f,e[i].t);
		}else res+=e[i].cost;
	}
	return res>=0.0;
}

int main(void){
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++){
		scanf("%d%d%d%d",&e[i].f,&e[i].t,&e[i].c,&e[i].d);
	}
	double l=0.0,r=1000000.0;
	for(int i=0;i<100;i++){
		double mid=(l+r)/2;
		if(C(mid))r=mid;
		else l=mid;
	}
	printf("%.9f\n",r);
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3488
final_rank: 4

code_snippet: #include<bits/stdc++.h>
 
using namespace std;
 
int N, M;
 
struct edge
{
  int u, v, cost, time;
  double p;
 
  edge(int u, int v, int cost, int time) : u(u), v(v), cost(cost), time(time) {};
 
  bool operator<(const edge &e) const
  {
    return p < e.p;
  }
 
};
 
typedef vector< edge > Edges;
 
class DisjointSet
{
private:
  vector< int > rank, p;
 
  void link(int x, int y)
  {
    if(rank[x] > rank[y]) {
      p[y] = x;
    } else {
      p[x] = y;
      if(rank[x] == rank[y]) rank[y]++;
    }
  }
 
public:
  DisjointSet() {}
 
  DisjointSet(int size)
  {
    rank.resize(size, 0);
    p.resize(size, 0);
  }
 
  void makeSet(int x)
  {
    p[x] = x, rank[x] = 0;
  }
 
  void Union(int x, int y)
  {
    link(findSet(x), findSet(y));
  }
 
  int findSet(int x)
  {
    return (x != p[x] ? p[x] = findSet(p[x]) : p[x]);
  }
};
 
double kruskal(Edges &edges, int V)
{
  sort(edges.rbegin(), edges.rend());
  DisjointSet uf_tree(V);
  for(int i = 0; i < V; i++) {
    uf_tree.makeSet(i);
  }
  double ret = 0;
  for(int i = 0; i < edges.size(); i++) {
    edge &e = edges[i];
    ret += e.p;
  }
  for(int i = 0; i < edges.size(); i++) {
    edge &e = edges[i];
    if(uf_tree.findSet(e.u) != uf_tree.findSet(e.v)) {
      uf_tree.Union(e.u, e.v);
      ret -= e.p;
    }
  }
  return ret;
}
 
bool calc(Edges &edges, double value)
{
  double ret = 0.0;
  for(int i = 0; i < edges.size(); i++) {
    edge &e = edges[i];
    e.p = (double) e.cost - (double) e.time * value;
  }
  return kruskal(edges, N) <= 0.0;
}
 
int main()
{
  Edges edges;
  scanf("%d %d", &N, &M);
  for(int i = 0; i < M; i++) {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    edges.push_back(edge(a, b, d, c));
  }
  double row = 0.0, high = 1e9;
  for(int i = 0; i < 100; i++) {
    double mid = (row + high) / 2;
    if(calc(edges, mid)) high = mid;
    else row = mid;
  }
  cout << fixed << setprecision(5) << (high + row) / 2 << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 3440
final_rank: 2

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cmath>

constexpr double EPS = (1e-10);
constexpr double INF = 252521;
#define equals(a, b) (fabs(a - b) < EPS)

std::vector<int> par, rnk;

void init(int n)
{
    par.resize(n); rnk.resize(n);
    for (int i = 0; i < n; i++) {
        par[i] = i;
        rnk[i] = 0;
    }
}

int find(int x)
{
    if (par[x] == x) {
        return x;
    }
    return par[x] = find(par[x]);
}

void unite(int x, int y)
{
    x = find(x);
    y = find(y);

    if (x == y) return;

    if (rnk[x] < rnk[y]) {
        par[x] = y;
    } else {
        par[y] = x;
        if (rnk[x] == rnk[y]) {
            rnk[x]++;
        }
    }
}

bool same(int x, int y)
{
    return (find(x) == find(y));
}

struct Edge {
    int u, v;
    double w;

    Edge() {}
    Edge(int u, int v, double w) :
        u{u}, v{v}, w{w} {}
};

struct Data {
    int u, v;
    double c, t;

    Data() {}
    Data(int u, int v, double c, double t) :
        u{u}, v{v}, c{c}, t{t} {}
};

int N, M;
std::vector<Data> d;
std::vector<Edge> es;

double kruskal()
{
    sort(es.begin(), es.end(), [](const Edge& e1, const Edge& e2) {
            return e1.w > e2.w;
    });
    
    init(N); 
    double tw = 0;
    for (Edge& e : es) {
        if (!same(e.u, e.v)) {
            unite(e.u, e.v);                       
        } else {
            tw += e.w;
        }
    }    
    return tw;
}

bool c(double x)
{
    for (int i = 0; i < M; i++) {
        es[i].u = d[i].u;
        es[i].v = d[i].v;
        es[i].w = d[i].t - x * d[i].c;
    }
    return kruskal() >= 0;
}

double solve()
{
    double lb = 0, ub = INF;
    for (int i = 0; i < 50; i++) {
        double mid = (lb + ub) / 2;
        if (c(mid)) {
            lb = mid;
        } else {
            ub = mid;
        }
    }
    return ub;
}

int main()
{
    scanf("%d %d", &N, &M);
    d.resize(M); es.resize(M);
    
    for (int i = 0; i < M; i++) {
        scanf("%d %d %lf %lf", &d[i].u, &d[i].v, &d[i].c, &d[i].t);
    }
    
    auto res = solve();
    printf("%.15f\n", (equals(res, INF) ? 0 : res));
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3392
final_rank: 1

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

struct UF{
  int par[10000];
  int size[10000];
  void init(int n){
    for(int i=0;i<n;i++){
      par[i]=i;
      size[i]=1;
    }
  }
  int find(int x){
    if(x==par[x])return x;
    return par[x]=find(par[x]);
  }
  void unite(int x,int y){
    x=find(x),y=find(y);
    if(x==y)return;
    if(size[x]<size[y])swap(x,y);
    par[y]=x;
    size[x]+=size[y];
  }
  bool same(int x,int y){
    return ( find(x)==find(y) );
  }
};

struct edge{
  int from;
  int to;
  int A;
  int B;
};

int N,M;
vector<edge> edges;

bool check(double K){
  typedef pair<double,int> P;
  vector<P> tmp;

  for(int i=0;i<(int)edges.size();i++){
    edge e=edges[i];

    tmp.push_back(  P( (double)e.B-(double)e.A*K , i ) );
  }
  sort(tmp.begin(),tmp.end());
  reverse(tmp.begin(),tmp.end());
  UF uf;
  uf.init(N);
  
  double sum=0;
  for(int i=0;i<(int)tmp.size();i++){
    edge e=edges[ tmp[i].second ];
    
    if( uf.same(e.from,e.to ) ){
      sum+=tmp[i].first;
    }else{
      uf.unite(e.from,e.to);
    }
  }

  if(uf.size[ uf.find(0) ]!=N)return false;
  return ( sum<=0.0 );
}

int main(){
  cin>>N>>M;
  for(int i=0;i<M;i++){
    int from,to,A,B;
    cin>>from>>to>>A>>B;
    edges.push_back( (edge){from,to,A,B} );
  }

  double left=0, right=1e7, mid;
  for(int i=0;i<100;i++){
    mid=(left+right)/2.0;
    if( check(mid) )right=mid;
    else left=mid;
  }
  printf("%.10f\n",left);
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3600
final_rank: 7

code_snippet: #include<bits/stdc++.h>
 using namespace std;
#define INF 1000000000
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
typedef long long LL;
typedef pair<double,int> P;
int n,m;
int a[10001];
int b[10001];
int c[10001];
int d[10001];


//????°???¨?????¨
#define MAX_N 20001
int par1[MAX_N];
int rank1[MAX_N];

//?????????
void init(int n){
   for(int i=0;i<n;i++){
       par1[i]=i;
       rank1[i]=0;
   }
}
//??¨??????????±???????
int find(int x){
    if(par1[x]==x){
       return x;
    }else{
       return par1[x]=find(par1[x]);
    }
}
//x??¨y????±??????????????????????
void unite(int x,int y){
   x=find(x);
   y=find(y);
   if(x==y) return;
   if(rank1[x]<rank1[y]){
        par1[x]=y;
   }else{
        par1[y]=x;
        if(rank1[x]==rank1[y]){
             rank1[x]++;
        }
   }
}
//x??¨y???????????????????±????????????????
bool same(int x,int y){
     return find(x) == find(y);
}

//MST
double MST(vector<P> ma){
   init(n+10);
   double cost=0;
   for(auto it=ma.begin();it!=ma.end();it++){
      int aa=a[it->second];
      int bb=b[it->second];
      if(!same(aa,bb)){
          unite(aa,bb);
      }else{
          cost+=it->first;
          //cout<<it->first<<endl;
      }
   }
   return cost;
}

bool check(double x){
   //?????????????????????
   vector<P> ma;
   //
   REP(i,m){
      //cout<<"X"<<x<<endl;
      double aa=(x*c[i]-d[i]);
      ma.push_back(make_pair(aa,i));
   }
   sort(ma.begin(),ma.end());
   //cout<<MST(ma)<<endl;
   return MST(ma)>=0;
}

double binary_search(){
   double lb=0;
   double ub=1e10;
   REP(i,300){
       double mid=(lb+ub)/2;
       if(check(mid)){
          ub=mid;
       }else{
          lb=mid;
       }
   }
   return ub;
}

int main(){
    cin>>n>>m;
    REP(i,m){
        cin>>a[i]>>b[i]>>c[i]>>d[i];
    }
    //cout<<check()<<endl;
    cout<<fixed<<setprecision(12)<<binary_search()<<endl;
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3644
final_rank: 19

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

#define CIN_ONLY if(1)
struct cww{cww(){
    CIN_ONLY{
        cout<<fixed;
        ios::sync_with_stdio(false);cin.tie(0);
    }
}}star;
#define fin "\n"
#define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second
#define pb push_back
#define DEBUG if(0)
#define REC(ret, ...) std::function<ret (__VA_ARGS__)>
template <typename T>inline bool chmin(T &l,T r)
{bool a=l>r;if(a)l=r;return a;}
template <typename T>inline bool chmax(T &l,T r)
{bool a=l<r;if(a)l=r;return a;}
template <typename T>
istream& operator>>(istream &is,vector<T> &v){
    for(auto &it:v)is>>it;
    return is;
}
int a[11234];
int b[11234];
double c[11234];
double d[11234];


namespace _DSU{
    int cnt=0;
    int mem[2][21234];
    int* get(){
        cnt=(cnt+1)%2;
        return mem[cnt];
    }
}
class UnionFind{
private:
    int *par,*rank;
    int find(int x){
	if (par[x] == x) return x;
	else return par[x] = find(par[x]);
    }
public:
    UnionFind(int n,int *par,int *rank) :par(par),rank(rank){
	for(int i = 0; i < n; i++)par[i] = i,rank[i] = 0;
    }
        UnionFind(int n):UnionFind(n,_DSU::get(),_DSU::get()){}
    bool unite(int x, int y){
	x = find(x);y = find(y);
	if (x == y)return false;
	if (rank[x] < rank[y]) par[x] = y;
	else{
	    par[y] = x;
	    if (rank[x] == rank[y])rank[x]++;
	}
	return true;
    }
    bool same(int x, int y){
	return find(x) == find(y);
    }
};

typedef pair<double,int> P;
int main(){
    int n,m;
    cin>>n>>m;
    REP(i,m){
        cin>>a[i]>>b[i]>>c[i]>>d[i];
    }
    vector<P> E(m);
    double ok=1e11,ng=0;
    auto f=[&](double x){
        UnionFind uf(n);
        REP(i,m)E[i]=P(d[i]-c[i]*x,i);
        sort(ALL(E));
        reverse(ALL(E));
        double ret=0;
        REP(i,m){
            int e=E[i].se;
            if(!uf.unite(a[e],b[e])){
                ret+=E[i].fi;
            }
        }
        return ret<=0;
    };
    REP(i,300){
        const double mid=(ok+ng)/2;
        if(f(mid))ok=mid;
        else ng=mid;
    }
    cout<<ok<<endl;
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 3636
final_rank: 17