Problem:
Problem K: Chinol Choco
Problem
チョコレート会社チノルチョコは新しい店を
n
店建てることにした。
それぞれの店は各店長に建てたい場所の候補を2つ用意してもらい、どちらかの場所に建てる。
チノルチョコでは
m
種類のチョコレートを販売しており、それぞれ別の工場で製造している。
すべての店で全種類のチョコレートを販売する。
チノルチョコではチョコレートを搬送するためのトラックを1台しか所有しておらず、1台のトラックでは1店分のチョコレートしか運べない。
そのため、トラックは店から別の店へ移動する際にすべての工場を回る必要がある。
ある店から別の店へ移動する時の最短移動距離の最大が最小になるように店を配置した時の、最大の移動距離を求めよ。
同じ場所に複数の店や工場が存在することができる。
Input
入力は以下の形式で与えられる。
n
m
a
0
b
0
c
0
d
0
...
a
n
−1
b
n
−1
c
n
−1
d
n
−1
x
0
y
0
...
x
m
−1
y
m
−1
入力はすべて整数で与えられる。
1行目にチノルチョコの店の数
n
、チョコレートを製造している工場の数
m
が空白区切りで与えられる。
2行目から
n
行にそれぞれの店を建てる場所の候補の座標(
a
i
,
b
i
),(
c
i
,
d
i
)が空白区切りで与えられる。
2+
n
行目から
m
行に工場の座標(
x
i
,
y
i
)が空白区切りで与えられる。
Constraints
入力は以下の条件を満たす。
2 ≤
n
≤ 200
1 ≤
m
≤ 15
0 ≤
a
i
,
b
i
,
c
i
,
d
i
,
x
i
,
y
i
≤ 1000
Output
最短移動距離の最大が最小になるように店を配置した時の、最大の移動距離を出力せよ。
誤差が10
−6
を超えてはならない。
Sample Input 1
2 1
0 0 5 5
3 3 6 6
2 2
Sample Output 1
4.2426406871
Sample Input 2
2 2
0 0 6 0
7 0 3 0
4 0
5 0
Sample Output 2
3.0000000000

Submitted solutions:

code_snippet: // AOJ #3023 Chinol Choco
// 2025.3.25

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

#define gc() getchar_unlocked()

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

const double INF = 1e18;

struct Pt { double x, y; };

inline double d(const Pt &a, const Pt &b) {
    double dx = a.x - b.x, dy = a.y - b.y;
    return sqrt(dx*dx + dy*dy);
}

struct Con {
    int i, j, p, q;
    double cost;
};

int main(){
    int n = Cin(), m = Cin();
    vector<vector<Pt>> s(n, vector<Pt>(2));
    for (int i = 0; i < n; i++)
        s[i][0].x = Cin(), s[i][0].y = Cin(), s[i][1].x = Cin(), s[i][1].y = Cin();
    vector<Pt> f(m);
    for (int i = 0; i < m; i++) f[i].x = Cin(), f[i].y = Cin();

    vector<vector<double>> tsp(m, vector<double>(m, INF));
    for (int s0 = 0; s0 < m; s0++){
        int N = 1 << m;
        vector<vector<double>> dp(N, vector<double>(m, INF));
        dp[1 << s0][s0] = 0;
        for (int mask = 0; mask < N; mask++){
            for (int j = 0; j < m; j++){
                if(mask & (1 << j)){
                    double cur = dp[mask][j];
                    if(cur == INF) continue;
                    for (int k = 0; k < m; k++){
                        if(!(mask & (1 << k))){
                            int nm = mask | (1 << k);
                            dp[nm][k] = min(dp[nm][k], cur + d(f[j], f[k]));
                        }
                    }
                }
            }
        }
        for (int e = 0; e < m; e++) tsp[s0][e] = dp[N-1][e];
    }

    vector<vector<array<double,4>>> cost(n, vector<array<double,4>>(n));
    vector<Con> cons;
    double mx = 0;
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            if(i == j) continue;
            for (int p = 0; p < 2; p++){
                for (int q = 0; q < 2; q++){
                    double best = INF;
                    for (int a = 0; a < m; a++){
                        double d1 = d(s[i][p], f[a]);
                        for (int b = 0; b < m; b++){
                            double d2 = d(f[b], s[j][q]);
                            best = min(best, d1 + tsp[a][b] + d2);
                        }
                    }
                    cost[i][j][p*2 + q] = best;
                    mx = max(mx, best);
                    cons.push_back({i, j, p, q, best});
                }
            }
        }
    }

    auto check = [&](double mid) -> bool {
        int V = 2 * n;
        vector<vector<int>> g(V), rg(V);
        for (auto &c : cons) {
            if(c.cost > mid){
                int A = (c.p == 0 ? 2 * c.i + 1 : 2 * c.i);
                int B = (c.q == 0 ? 2 * c.j + 1 : 2 * c.j);
                int nA = A ^ 1, nB = B ^ 1;
                g[nA].push_back(B);
                g[nB].push_back(A);
                rg[B].push_back(nA);
                rg[A].push_back(nB);
            }
        }
        vector<int> order;
        vector<bool> vis(V, false);
        function<void(int)> dfs1 = [&](int v){
            vis[v] = true;
            for (int w : g[v]) if(!vis[w]) dfs1(w);
            order.push_back(v);
        };
        for (int i = 0; i < V; i++) if(!vis[i]) dfs1(i);

        vector<int> comp(V, -1);
        function<void(int, int)> dfs2 = [&](int v, int cl){
            comp[v] = cl;
            for (int w : rg[v]) if(comp[w] == -1) dfs2(w, cl);
        };
        int cl = 0;
        for (int i = V-1; i >= 0; i--){
            int v = order[i];
            if(comp[v] == -1) dfs2(v, cl++);
        }
        for (int i = 0; i < n; i++){
            if(comp[2*i] == comp[2*i+1]) return false;
        }
        return true;
    };

    double lo = 0, hi = mx, ans = hi;
    for (int iter = 0; iter < 60; iter++){
        double mid = (lo + hi) / 2;
        if(check(mid)) ans = mid, hi = mid;
        else lo = mid;
    }
    printf("%.10lf\n", ans);
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 13276
final_rank: 3

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

using CP = complex<long double>;

struct StronglyConnectedComponent {
  int n, k;
  vector<vector<int>> G, revG;
  vector<int> vs, cmp;
  vector<bool> used;
  StronglyConnectedComponent(int _n = 1) {
    n = _n;
    G.resize(n);
    revG.resize(n);
    used.resize(n, 0);
    cmp.resize(n);
  }

  bool add(int from, int to) {
    G[from].push_back(to);
    revG[to].push_back(from);
    return 1;
  }
  void dfs(int v) {
    used[v] = true;
    for (auto to : G[v])
      if (!used[to]) dfs(to);
    vs.push_back(v);
  }
  void rdfs(int v) {
    used[v] = true;
    cmp[v] = k;
    for (auto to : revG[v])
      if (!used[to]) rdfs(to);
  }
  int solve() {
    used.assign(n, 0);
    vs.clear();
    for (int v = 0; v < n; ++v)
      if (!used[v]) dfs(v);
    used.assign(n, 0);
    k = 0;
    for (int i = (int)vs.size() - 1; i >= 0; --i)
      if (!used[vs[i]]) {
        rdfs(vs[i]);
        ++k;
      }
    return k;
  }
};

struct TwoSAT {
  int n;
  StronglyConnectedComponent scc;
  TwoSAT(int _n = 1) : n(_n), scc(2 * n) {}
  void add(int a, bool b, int c, bool d) {
    scc.add(a + b * n, c + (!d) * n);
    scc.add(c + d * n, a + (!b) * n);
  }
  bool solve() {
    scc.solve();
    for (int i = 0; i < n; ++i)
      if (scc.cmp[i] == scc.cmp[i + n]) return 0;
    return 1;
  }
};

int n, m;
vector<CP> fact, shop[2];
vector<vector<vector<long double>>> dp;
vector<vector<vector<vector<long double>>>> dist;

long double solve();
bool check(long double x);

int main() {
  cin >> n >> m;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < 2; ++j) {
      int x, y;
      cin >> x >> y;
      shop[j].emplace_back(x, y);
    }
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    fact.emplace_back(x, y);
  }
  cout << fixed << setprecision(10);
  cout << solve() << endl;
  return 0;
}

long double solve() {
  {  // bit dp
    dp.assign(m, vector(m, vector<long double>(1 << m, inf)));
    for (int j = 0; j < m; ++j) {
      dp[j][j][1 << j] = 0;
      for (int i = 3; i < (1 << m); ++i)
        if ((i >> j & 1) && (i ^ (1 << j)))
          for (int k = 0; k < m; ++k)
            if ((i >> k & 1) && j != k)
              for (int l = 0; l < m; ++l)
                if ((i >> l & 1) && k != l) {
                  dp[j][k][i] = min(dp[j][k][i], dp[j][l][i ^ (1 << k)] +
                                                     abs(fact[k] - fact[l]));
                }
    }
  }
  dist.assign(n, vector(n, vector(2, vector<long double>(2, inf))));
  for (int i = 0; i < n; ++i)
    for (int j = i; j < n; ++j)
      if (i != j)
        for (int k = 0; k < m; ++k)
          for (int l = 0; l < m; ++l)
            for (int x = 0; x < 2; ++x)
              for (int y = 0; y < 2; ++y)
                dist[i][j][x][y] =
                    min(dist[i][j][x][y], dp[k][l][(1 << m) - 1] +
                                              abs(fact[k] - shop[x][i]) +
                                              abs(fact[l] - shop[y][j]));
  long double l = 0, r = inf;
  for (int time = 0; time < 100; ++time) {
    long double mid = (l + r) / 2;
    if (check(mid))
      r = mid;
    else
      l = mid;
  }
  return r;
}

bool check(long double x) {
  TwoSAT sat(n);
  for (int i = 0; i < n; ++i)
    for (int j = i + 1; j < n; ++j)
      for (int k = 0; k < 2; ++k)
        for (int l = 0; l < 2; ++l)
          if (dist[i][j][k][l] > x) sat.add(i, !k, j, !l);
  return sat.solve();
}
accuracy: 1
time_ms: 1690
memory_kb: 128256
final_rank: 13

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



#define SIZE 205

struct LOC{

	double x,y;
};

int N,M;
int POW[16];
double dp[15][1<<15][15];
double min_dist[SIZE][SIZE][2][2];
LOC shop[SIZE][2],factory[15];


//scc
int group_index;
bool check[2*SIZE];
int table[2*SIZE];
vector<int> G[2*SIZE];
vector<int> reverse_G[2*SIZE];
stack<int> S;

void dfs(int node_id){
	check[node_id] = true;

	for(int i = 0; i < G[node_id].size(); i++){
		if(!check[G[node_id][i]])dfs(G[node_id][i]);
	}
	S.push(node_id);
}

void reverse_dfs(int node_id){
	check[node_id] = true;

	table[node_id] = group_index;

	for(int i = 0; i < reverse_G[node_id].size(); i++){
		if(!check[reverse_G[node_id][i]])reverse_dfs(reverse_G[node_id][i]);
	}
}

bool is_OK(){

	for(int i = 0; i < 2*N; i++)check[i] = false;

	//まずは帰りがけ順を計算
	for(int i = 0; i < 2*N;i++){
		if(!check[i])dfs(i);
	}

	for(int i = 0; i < 2*N;i++)check[i] = false;

	group_index = -1;
	//ノードを、帰りがけ順の逆順に、各強連結成分(グループ)に分解
	while(!S.empty()){
		if(!check[S.top()]){
			group_index++;

			reverse_dfs(S.top());
		}
		S.pop();
	}

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

		if(table[i] == table[i+N])return false;
	}

	return true;
}

double calc_dist(LOC a,LOC b){

	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}


int main(){

	POW[0] = 1;
	for(int i = 1; i <= 15; i++){

		POW[i] = POW[i-1]*2;
	}

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

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

			scanf("%lf %lf",&shop[i][k].x,&shop[i][k].y);
		}
	}

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

		scanf("%lf %lf",&factory[i].x,&factory[i].y);
	}

	for(int start = 0; start < M; start++){
		for(int state = 0; state < POW[M]; state++){
			for(int last = 0; last < M; last++){

				dp[start][state][last] = BIG_NUM;
			}
		}
		dp[start][POW[start]][start] = 0;
	}

	for(int start = 0; start < M; start++){
		for(int state = 0; state < POW[M]; state++){
			for(int last = 0; last < M; last++){
				if(fabs(dp[start][state][last]-BIG_NUM) < EPS)continue;

				for(int next = 0; next < M; next++){
					if(state & POW[next])continue;

					int next_state = state+POW[next];
					double next_dist = dp[start][state][last]+calc_dist(factory[last],factory[next]);

					dp[start][next_state][next] = min(dp[start][next_state][next],next_dist);
				}
			}
		}
	}

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++){
			if(k == i)continue;
			for(int a = 0; a < 2; a++){
				for(int b = 0; b < 2; b++){
					min_dist[i][k][a][b] = BIG_NUM;

					for(int start = 0; start < M; start++){
						for(int goal = 0; goal< M; goal++){

							double tmp_dist = calc_dist(shop[i][a],factory[start])+calc_dist(shop[k][b],factory[goal]);
							tmp_dist += dp[start][POW[M]-1][goal];

							min_dist[i][k][a][b] = min(min_dist[i][k][a][b],tmp_dist);
						}
					}
				}
			}
		}
	}

	double left = 0,right = 100000,mid = (left+right)/2;
	double ans = BIG_NUM;

	while(left+EPS < right){

		for(int i = 0; i < 2*SIZE; i++){
			G[i].clear();
			reverse_G[i].clear();
		}

		for(int i = 0; i < N; i++){
			for(int k = 0; k < N; k++){
				if(k == i)continue;
				for(int a = 0; a < 2; a++){
					for(int b = 0; b < 2; b++){

						if(min_dist[i][k][a][b] > mid){ //a→bへはパスを張れない

							int from = i;
							if(a == 1){

								from += N;
							}
							int to = k;
							if(b == 0){ //bが候補0→候補1に辺を張る,bが候補1→候補0に辺を張る

								to += N;
							}
							G[from].push_back(to);
							reverse_G[to].push_back(from);
						}
					}
				}
			}
		}

		if(is_OK()){

			ans = mid;
			right = mid-EPS;
		}else{

			left = mid+EPS;
		}
		mid = (left+right)/2;
	}

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

	return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 63640
final_rank: 7

code_snippet: #include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<math.h>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<assert.h>
#include<numeric>
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;

struct StronglyConnectedComponents{
    vector<int> used,cmp,vs;
    vector<vector<int>> v,rv;
    StronglyConnectedComponents(int n):used(n),cmp(n,-1),v(n),rv(n){}

    void add_edge(int x,int y){
        v[x].push_back(y);
        rv[y].push_back(x);
    }
    void dfs(int x){
        used[x]=true;
        for(auto to:v[x])if(!used[to])dfs(to);
        vs.push_back(x);
    }

    void rdfs(int x,int k){
        cmp[x]=k;
        for(auto to:rv[x])if(cmp[to]==-1)rdfs(to,k);
    }

    int scc(){
        rep(i,used.size())if(!used[i])dfs(i);
        reverse(vs.begin(),vs.end());
        int k=0;
        for(auto x:vs)if(cmp[x]==-1)rdfs(x,k++);
        return k;
    }
    void build(vector<vector<int>> &g){
        int k=scc();
        g.resize(k);
        set<pair<int,int>> used;
        rep(i,v.size()){
            for(auto& to:v[i]){
                int x=cmp[i],y=cmp[to];
                if(x==y||used.count({x,y}))continue;
                g[x].push_back(y);
                used.emplace(x,y);
            }
        }
    }
};

using Point  =complex<double>;
int main(){
    int n,m;
    cin>>n>>m;
    Point p[n][2];
    rep(i,n)rep(j,2){
        int x,y;
        cin>>x>>y;
        p[i][j]=Point(x,y);
    }
    Point f[m];
    rep(i,m){
        int x,y;
        cin>>x>>y;
        f[i]=Point(x,y);
    }
    double dist[m][m][1<<m];
    rep(i,m){
        rep(j,m)rep(k,1<<m)dist[i][j][k]=inf;
        dist[i][i][1<<i]=0;
        rep(j,1<<m){
            if((j&(1<<i))==0)continue;
            rep(k,m){
                if(((1<<k)&j)==0)continue;
                rep(l,m){
                    //if(k==l||k==i||l==i)continue;
                    if(((1<<l)&j)==0)continue;
                    dist[i][k][j]=min(dist[i][k][j],dist[i][l][j-(1<<k)]+abs(f[k]-f[l]));

                }
            }
        }
    }
    double d[n][n][2][2];
    rep(i,n)rep(j,n)rep(k,2)rep(l,2)d[i][j][k][l]=inf;
    rep(i,n)rep(j,n)rep(k,2)rep(l,2){
        if(i==j)continue;
        rep(x,m)rep(y,m){
            d[i][j][k][l]=min(d[i][j][k][l],abs(f[x]-p[i][k])+dist[x][y][(1<<m)-1]+abs(f[y]-p[j][l]));
        }
    }
    double ok=inf, ng=0;
    rep(_,60){
        double mid = (ok+ng)/2;
        StronglyConnectedComponents scc(2*n);
        rep(i,n)rep(j,n){
            if(i==j)continue;
            if(d[i][j][0][0]>mid){
                scc.add_edge(2*i, 2*j+1);
            }
            if(d[i][j][0][1]>mid){
                scc.add_edge(2*i, 2*j);
            }
            if(d[i][j][1][0]>mid){
                scc.add_edge(2*i+1, 2*j+1);
            }
            if(d[i][j][1][1]>mid){
                scc.add_edge(2*i+1, 2*j);
            }
            
        }
        scc.scc();
        bool can=true;
        rep(i,n){
            if(scc.cmp[2*i]==scc.cmp[2*i+1])can=false;
        }
        if(can)ok=mid;
        else ng=mid;
    }
    cout<<fixed<<setprecision(12)<<ok<<endl;
    return 0;
}
accuracy: 1
time_ms: 1070
memory_kb: 63404
final_rank: 10

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 SCC{
    int V;
    vector<vector<int>> G, rG;
    vector<int> vs; // 帰りがけ順の並び
    vector<int> cmp; //属する強連結成分トポロジカル順序
    vector<bool> used;

    SCC(){}
    SCC(int n){
        V = n;
        G = vector<vector<int>>(n);
        rG = vector<vector<int>>(n);
    }

    void add_edge(int from, int to){
        G[from].push_back(to);
        rG[to].push_back(from);
    }

    void dfs(int v){
        used[v] = true;
        rep(i,G[v].size())if(!used[G[v][i]]) dfs(G[v][i]);
        vs.push_back(v);
    }

    void rdfs(int v, int k){
        used[v]=true;
        cmp[v]=k;
        rep(i,rG[v].size())if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }

    int scc(){
        used = vector<bool>(V,false);
        vs.clear();
        rep(i,V)if(!used[i]) dfs(i);

        used = vector<bool>(V,false);
        cmp = vector<int>(V);
        int num_scc = 0;
        for(int i=vs.size()-1; i>=0; --i)if(!used[vs[i]]) rdfs(vs[i],num_scc++);
        return num_scc;
    }
};

struct TwoSat{
    int v;
    SCC graph;

    // v literals
    // 0~v-1: true
    // v~2v-1: false

    TwoSat(int num_literal){
        v = num_literal;
        graph = SCC(2*v);
    }

    inline int num(int id, bool b){return id+(b?0:v);}

    void add_clause(int x, bool X, int y, bool Y){
        graph.add_edge(num(x,!X), num(y,Y));
        graph.add_edge(num(y,!Y), num(x,X));
    }

    // 割り当てが可能か調べる
    bool calc(){
        graph.scc();
        rep(i,v)if(graph.cmp[i]==graph.cmp[v+i]) return false;
        return true;
    }

    // リテラルの真偽値を返す
    vector<bool> get_literals(){
        assert(calc());
        vector<bool> res(v);
        rep(i,v) res[i] = (graph.cmp[i]>graph.cmp[v+i]);
        return res;
    }
};

struct P{
    int x,y;
    void READ(){
        cin >>x >>y;
    }
};

double calc_dist(P p, P q){
    double X = abs(p.x-q.x);
    double Y = abs(p.y-q.y);
    return sqrt(X*X + Y*Y);
}

const int N = 15;
const double INF = 1e6;

double dist[N][N];

double d[N][N];
double dp[1<<N][N];
double D[200][2][200][2];

void calc(int start, int n){
    fill(dp[0],dp[1<<N],INF);
    dp[1<<start][start] = 0;
    rep(mask,1<<n)rep(i,n)if(mask>>i&1){
        rep(j,n)if(!(mask>>j&1)){
            int nmask = mask|(1<<j);
            dp[nmask][j] = min(dp[nmask][j], dp[mask][i]+dist[i][j]);
        }
    }
    rep(i,n) d[start][i] = dp[(1<<n)-1][i];
}


int main(){
    int n,m;
    cin >>n >>m;

    vector<vector<P>> store(n,vector<P>(2));
    vector<P> factory(m);
    rep(i,n)rep(j,2) store[i][j].READ();
    rep(i,m) factory[i].READ();

    rep(i,m)rep(j,m) dist[i][j] = calc_dist(factory[i], factory[j]);
    rep(i,m) calc(i,m);

    rep(i,n)rep(j,i)rep(ii,2)rep(jj,2){
        double tt = INF;
        rep(from,m)rep(to,m){
            double tmp = calc_dist(store[i][ii], factory[from]) + d[from][to] + calc_dist(factory[to], store[j][jj]);
            tt = min(tt,tmp);
        }
        D[i][ii][j][jj] = tt;
    }

    auto valid = [&](double lim){
        TwoSat solver(n);
        rep(i,n)rep(j,i)rep(ii,2)rep(jj,2){
            if(D[i][ii][j][jj]>lim) solver.add_clause(i,!ii,j,!jj);
        }
        return solver.calc();
    };

    double l=0, r=INF;
    rep(_,50){
        double mid=(l+r)/2;
        if(valid(mid)) r=mid;
        else l=mid;
    }
    printf("%.10f\n", r);
    return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 9752
final_rank: 2

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 P{
    int x,y;
};

using pp = pair<P,P>;

P READ_P(){
    int x,y;
    cin >>x >>y;
    return {x,y};
}

double calc_dist(P p, P q){
    double X = abs(p.x-q.x);
    double Y = abs(p.y-q.y);
    return sqrt(X*X + Y*Y);
}

const int N = 15;
const double INF = 1e8;

double dist[N][N];

double d[N][N];
double dp[1<<N][N];

void calc(int start, int n){
    fill(dp[0],dp[1<<N],INF);
    dp[1<<start][start] = 0;
    rep(mask,1<<n){
        rep(i,n)if(mask>>i&1){
            rep(j,n)if(!(mask>>j&1)){
                int nmask = mask|(1<<j);
                dp[nmask][j] = min(dp[nmask][j], dp[mask][i]+dist[i][j]);
            }
        }
    }

    rep(i,n) d[start][i] = dp[(1<<n)-1][i];
}

struct SCC{
    int V;
    vector<vector<int>> G, rG;
    vector<int> vs; // 帰りがけ順の並び
    vector<int> cmp; //属する強連結成分トポロジカル順序
    vector<bool> used;

    SCC(){}
    SCC(int n){
        V = n;
        G = vector<vector<int>>(n);
        rG = vector<vector<int>>(n);
    }

    void add_edge(int from, int to){
        G[from].push_back(to);
        rG[to].push_back(from);
    }

    void dfs(int v){
        used[v] = true;
        rep(i,G[v].size())if(!used[G[v][i]]) dfs(G[v][i]);
        vs.push_back(v);
    }

    void rdfs(int v, int k){
        used[v]=true;
        cmp[v]=k;
        rep(i,rG[v].size())if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }

    int scc(){
        used = vector<bool>(V,false);
        vs.clear();
        rep(i,V)if(!used[i]) dfs(i);

        used = vector<bool>(V,false);
        cmp = vector<int>(V);
        int num_scc = 0;
        for(int i=vs.size()-1; i>=0; --i)if(!used[vs[i]]) rdfs(vs[i],num_scc++);
        return num_scc;
    }
};

struct TwoSat{
    int v;
    SCC graph;

    // v literals
    // 0~v-1: true
    // v~2v-1: false

    TwoSat(int num_literal){
        v = num_literal;
        graph = SCC(2*v);
    }

    inline int num(int id, bool b){return id+(b?0:v);}

    void add_clause(int x, bool X, int y, bool Y){
        graph.add_edge(num(x,!X), num(y,Y));
        graph.add_edge(num(y,!Y), num(x,X));
    }

    // 割り当てが可能か調べる
    bool calc(){
        graph.scc();
        rep(i,v)if(graph.cmp[i]==graph.cmp[v+i]) return false;
        return true;
    }

    // リテラルの真偽値を返す
    vector<bool> get_literals(){
        assert(calc());
        vector<bool> res(v);
        rep(i,v) res[i] = (graph.cmp[i]>graph.cmp[v+i]);
        return res;
    }
};

double D[200][2][200][2];

int main(){
    int n,m;
    cin >>n >>m;

    vector<vector<P>> store(n);
    rep(i,n)rep(j,2) store[i].pb(READ_P());

    vector<P> factory(m);
    rep(i,m) factory[i] = READ_P();

    rep(i,m)rep(j,m) dist[i][j] = calc_dist(factory[i],factory[j]);
    rep(i,m) calc(i,m);

    rep(i,n)rep(j,i)rep(ii,2)rep(jj,2){
        double tt = INF;
        rep(from,m)rep(to,m){
            double tmp = calc_dist(store[i][ii], factory[from]);
            tmp += d[from][to];
            tmp += calc_dist(factory[to], store[j][jj]);
            tt = min(tt,tmp);
        }
        D[i][ii][j][jj] = tt;
    }

    auto valid = [&](double lim){
        TwoSat solver(n);
        rep(i,n)rep(j,i)rep(ii,2)rep(jj,2){
            if(D[i][ii][j][jj]>lim) solver.add_clause(i,!ii,j,!jj);
        }
        return solver.calc();
    };

    double l=0, r=INF;
    rep(_,60){
        double mid=(l+r)/2;
        if(valid(mid)) r=mid;
        else l=mid;
    }
    printf("%.10f\n", r);
    return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 9724
final_rank: 1

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 P{
    int x,y;
};

using pp = pair<P,P>;

P READ_P(){
    int x,y;
    cin >>x >>y;
    return {x,y};
}

double calc_dist(P p, P q){
    double X = abs(p.x-q.x);
    double Y = abs(p.y-q.y);
    return sqrt(X*X + Y*Y);
}

const int N = 15;
const double INF = 1e8;

double dist[N][N];

double d[N][N];
double dp[1<<N][N];

void calc(int start, int n){
    fill(dp[0],dp[1<<N],INF);
    dp[1<<start][start] = 0;
    rep(mask,1<<n){
        rep(i,n)if(mask>>i&1){
            rep(j,n)if(!(mask>>j&1)){
                int nmask = mask|(1<<j);
                dp[nmask][j] = min(dp[nmask][j], dp[mask][i]+dist[i][j]);
            }
        }
    }

    rep(i,n) d[start][i] = dp[(1<<n)-1][i];
}

struct SCC{
    int V;
    vector<vector<int>> G, rG;
    vector<int> vs; // 帰りがけ順の並び
    vector<int> cmp; //属する強連結成分トポロジカル順序
    vector<bool> used;

    SCC(){}
    SCC(int n){
        V = n;
        G = vector<vector<int>>(n);
        rG = vector<vector<int>>(n);
    }

    void add_edge(int from, int to){
        G[from].push_back(to);
        rG[to].push_back(from);
    }

    void dfs(int v){
        used[v] = true;
        rep(i,G[v].size())if(!used[G[v][i]]) dfs(G[v][i]);
        vs.push_back(v);
    }

    void rdfs(int v, int k){
        used[v]=true;
        cmp[v]=k;
        rep(i,rG[v].size())if(!used[rG[v][i]]) rdfs(rG[v][i],k);
    }

    int scc(){
        used = vector<bool>(V,false);
        vs.clear();
        rep(i,V)if(!used[i]) dfs(i);

        used = vector<bool>(V,false);
        cmp = vector<int>(V);
        int num_scc = 0;
        for(int i=vs.size()-1; i>=0; --i)if(!used[vs[i]]) rdfs(vs[i],num_scc++);
        return num_scc;
    }
};

struct TwoSat{
    int v;
    SCC graph;

    // v literals
    // 0~v-1: true
    // v~2v-1: false

    TwoSat(int num_literal){
        v = num_literal;
        graph = SCC(2*v);
    }

    inline int num(int id, bool b){return id+(b?0:v);}

    void add_clause(int x, bool X, int y, bool Y){
        graph.add_edge(num(x,!X), num(y,Y));
        graph.add_edge(num(y,!Y), num(x,X));
    }

    // 割り当てが可能か調べる
    bool calc(){
        graph.scc();
        rep(i,v)if(graph.cmp[i]==graph.cmp[v+i]) return false;
        return true;
    }

    // リテラルの真偽値を返す
    vector<bool> get_literals(){
        assert(calc());
        vector<bool> res(v);
        rep(i,v) res[i] = (graph.cmp[i]>graph.cmp[v+i]);
        return res;
    }
};

double D[N][2][N][2];

int main(){
    int n,m;
    cin >>n >>m;

    vector<vector<P>> store(n);
    rep(i,n)rep(j,2) store[i].pb(READ_P());

    vector<P> factory(m);
    rep(i,m) factory[i] = READ_P();

    rep(i,m)rep(j,m) dist[i][j] = calc_dist(factory[i],factory[j]);
    rep(i,m) calc(i,m);

    rep(i,n)rep(j,i)rep(ii,2)rep(jj,2){
        double tt = INF;
        rep(from,m)rep(to,m){
            double tmp = calc_dist(store[i][ii], factory[from]);
            tmp += d[from][to];
            tmp += calc_dist(factory[to], store[j][jj]);
            tt = min(tt,tmp);
        }
        D[i][ii][j][jj] = tt;
    }

    auto valid = [&](double lim){
        TwoSat solver(n);
        rep(i,n)rep(j,i)rep(ii,2)rep(jj,2){
            if(D[i][ii][j][jj]>lim) solver.add_clause(i,!ii,j,!jj);
        }
        return solver.calc();
    };

    double l=0, r=INF;
    rep(_,60){
        double mid=(l+r)/2;
        if(valid(mid)) r=mid;
        else l=mid;
    }
    printf("%.10f\n", r);
    return 0;
}
accuracy: 0.28888888888888886
time_ms: 380
memory_kb: 8412
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
int exf=0;

struct closure{
  int ai,af,bi,bf; 
  closure(int ai,int af,int bi,int bf):
    ai(ai), af(af), bi(bi), bf(bf) {}
};


void add_edge(int from,int to,mat &G,mat &rG){
  G[from].push_back(to);
  rG[to].push_back(from);
}

void dfs(int v,const mat &G,vec &used,vec &vs){
  used[v]=1;
  for(int to:G[v])
    if(!used[to])
      dfs(to,G,used,vs);
  vs.push_back(v);
}

void rdfs(int v,int k,const mat &rG,vec &used,vec &cmp){
  used[v]=1;
  cmp[v]=k;
  for(int to:rG[v])
    if(!used[to])
      rdfs(to,k,rG,used,cmp);
}

int scc(const mat &G,const mat &rG,vec &cmp){
  int n=G.size();
  cmp=vec(n);
  vec vs, used(n,0);
  for(int v=0;v<n;v++){
    if(!used[v])dfs(v,G,used,vs);
  }
  int k=0;
  reverse(vs.begin(),vs.end());

  used=vec(n,0);
  for(int i=0;i<n;i++){
    int v=vs[i];
    if(!used[v])rdfs(v,k++,rG,used,cmp);
  }
  return k;
}


bool sat2(int n,const vector<closure> &A){

  
  int m=A.size();
  
  mat G,rG;
  G.resize(n*2);
  rG.resize(n*2);

  for(int i=0;i<m;i++){
    closure cl=A[i];
    int ai=cl.ai,bi=cl.bi;
    int af=cl.af,bf=cl.bf;
    
    if(!af && bf){
      swap(ai,bi);
      swap(af,bf);
    }
    if(af && !bf){
      add_edge(ai+n,bi+n,G,rG);
      add_edge(bi  ,ai  ,G,rG);
    }
    if(af && bf){
      add_edge(ai+n,bi,G,rG);
      add_edge(bi+n,ai,G,rG);
    }
    if(!af && !bf){
      add_edge(ai,bi+n,G,rG);
      add_edge(bi,ai+n,G,rG);
    }
  }
  
  vec cmp, res(n,0), tmp;
  scc(G,rG,cmp);
  for(int i=0;i<n;i++){
    if(cmp[i]==cmp[i+n])return false;
  }
  return true;
}


int n,m;
double ax[200],ay[200],bx[200],by[200];
double cx[15],cy[15];

double dp[15][1<<15][15];

double f(double ax,double ay,double bx,double by){
  double X=ax-bx;
  double Y=ay-by;
  return sqrt(X*X+Y*Y);
}

double calc(double ax,double ay,double bx,double by){
  double res=1e9;
  for(int i=0;i<m;i++){
    for(int j=0;j<m;j++){
      res=min(res,f(ax,ay,cx[i],cy[i])+dp[i][(1<<m)-1][j]+f(bx,by,cx[j],cy[j]));
    }
  }
  return res;
}

double Mem[300][2][300][2];
int used[300][2][300][2];
double Calc(int a,int af,int b,int bf){
  if(used[a][af][b][bf])return Mem[a][af][b][bf];
  used[a][af][b][bf]=1;
  double x0 = ( af == 0 ? ax[a] : bx[a] );
  double y0 = ( af == 0 ? ay[a] : by[a] );
  double x1 = ( bf == 0 ? ax[b] : bx[b] );
  double y1 = ( bf == 0 ? ay[b] : by[b] );
  return Mem[a][af][b][bf]=calc( x0,y0,x1,y1);
}

bool mem;
int lastsize=-1;

bool check(double mid){

  vector< closure > v;
  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      bool f00=(Calc(i,0,j,0) < mid );
      bool f01=(Calc(i,0,j,1) < mid );
      bool f10=(Calc(i,1,j,0) < mid );
      bool f11=(Calc(i,1,j,1) < mid );
      
      if( !f00 ){
        v.emplace_back(i,1,j,1 );
      }
      if( !f01 ){
        v.emplace_back(i,1,j,0 );
      }
      if( !f10 ){
        v.emplace_back(i,0,j,1 );
      }
      if( !f11 ){
        v.emplace_back(i,0,j,0 );
      }
    }
  }

  
  return mem  = sat2( n, v );
}

double solve(){
  for(int i=0;i<m;i++)
    for(int j=0;j<(1<<m);j++)
      for(int k=0;k<m;k++)
        dp[i][j][k]=1e9;

  double maxm=0,mini=0;
  
  for(int i=0;i<m;i++){
    dp[i][(1<<i)][i]=0;
    for(int bit=0;bit<(1<<m);bit++){
      for(int pos=0;pos<m;pos++){
        for(int to=0;to<m;to++){
          double dx=cx[pos]-cx[to];
          double dy=cy[pos]-cy[to];
          double cost=sqrt(dx*dx+dy*dy);
          int nbit=bit|(1<<to);
          dp[i][nbit][to]=min(dp[i][nbit][to],dp[i][bit][pos]+cost);

          maxm=max( maxm , dp[i][nbit][to] + 3000 );
          if(nbit==(1<<m)-1){
            mini=min( mini, dp[i][nbit][to]  );
          }
          
        }
      }
    }
  }
  
  double left=0,right=maxm,mid;
  
  for(int i=0;i<100;i++){
    mid=(left+right)*0.5;
    if( check(mid) ){
      exf=1;
      right=mid;
    }    else {
      exf=0;
      left=mid;
    }
  }
  return left;
}

int main(){
  cin>>n>>m;
  for(int i=0;i<n;i++){
    cin>>ax[i]>>ay[i]>>bx[i]>>by[i];
  }
  for(int i=0;i<m;i++){
    cin>>cx[i]>>cy[i];
  }
  printf("%.10f\n",solve());
  return 0;
}
accuracy: 1
time_ms: 560
memory_kb: 66824
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
int exf=0;

struct closure{
  int ai,af,bi,bf; 
  closure(int ai,int af,int bi,int bf):
    ai(ai), af(af), bi(bi), bf(bf) {}
};


void add_edge(int from,int to,mat &G,mat &rG){
  G[from].push_back(to);
  rG[to].push_back(from);
}

void dfs(int v,const mat &G,vec &used,vec &vs){
  used[v]=1;
  for(int to:G[v])
    if(!used[to])
      dfs(to,G,used,vs);
  vs.push_back(v);
}

void rdfs(int v,int k,const mat &rG,vec &used,vec &cmp){
  used[v]=1;
  cmp[v]=k;
  for(int to:rG[v])
    if(!used[to])
      rdfs(to,k,rG,used,cmp);
}

int scc(const mat &G,const mat &rG,vec &cmp){
  int n=G.size();
  cmp=vec(n);
  vec vs, used(n,0);
  for(int v=0;v<n;v++){
    if(!used[v])dfs(v,G,used,vs);
  }
  int k=0;
  reverse(vs.begin(),vs.end());

  used=vec(n,0);
  for(int i=0;i<n;i++){
    int v=vs[i];
    if(!used[v])rdfs(v,k++,rG,used,cmp);
  }
  return k;
}


bool sat2(int n,const vector<closure> &A){

  
  int m=A.size();
  
  mat G,rG;
  G.resize(n*2);
  rG.resize(n*2);

  for(int i=0;i<m;i++){
    closure cl=A[i];
    int ai=cl.ai,bi=cl.bi;
    int af=cl.af,bf=cl.bf;
    
    if(!af && bf){
      swap(ai,bi);
      swap(af,bf);
    }
    if(af && !bf){
      add_edge(ai+n,bi+n,G,rG);
      add_edge(bi  ,ai  ,G,rG);
    }
    if(af && bf){
      add_edge(ai+n,bi,G,rG);
      add_edge(bi+n,ai,G,rG);
    }
    if(!af && !bf){
      add_edge(ai,bi+n,G,rG);
      add_edge(bi,ai+n,G,rG);
    }
  }
  
  vec cmp, res(n,0), tmp;
  scc(G,rG,cmp);
  for(int i=0;i<n;i++){
    if(cmp[i]==cmp[i+n])return false;
  }
  return true;
}


int n,m;
double ax[200],ay[200],bx[200],by[200];
double cx[15],cy[15];

double dp[15][1<<15][15];

double f(double ax,double ay,double bx,double by){
  double X=ax-bx;
  double Y=ay-by;
  return sqrt(X*X+Y*Y);
}

double calc(double ax,double ay,double bx,double by){
  double res=1e9;
  for(int i=0;i<m;i++){
    for(int j=0;j<m;j++){
      res=min(res,f(ax,ay,cx[i],cy[i])+dp[i][(1<<m)-1][j]+f(bx,by,cx[j],cy[j]));
    }
  }
  return res;
}

double Mem[300][2][300][2];
int used[300][2][300][2];
double Calc(int a,int af,int b,int bf){
  if(used[a][af][b][bf])return Mem[a][af][b][bf];
  used[a][af][b][bf]=1;
  double x0 = ( af == 0 ? ax[a] : bx[a] );
  double y0 = ( af == 0 ? ay[a] : by[a] );
  double x1 = ( bf == 0 ? ax[b] : bx[b] );
  double y1 = ( bf == 0 ? ay[b] : by[b] );
  return Mem[a][af][b][bf]=calc( x0,y0,x1,y1);
}

bool mem;
int lastsize=-1;

bool check(double mid){

  vector< closure > v;
  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      bool f00=(Calc(i,0,j,0) < mid );
      bool f01=(Calc(i,0,j,1) < mid );
      bool f10=(Calc(i,1,j,0) < mid );
      bool f11=(Calc(i,1,j,1) < mid );
      
      if( !f00 ){
        v.emplace_back(i,1,j,1 );
      }
      if( !f01 ){
        v.emplace_back(i,1,j,0 );
      }
      if( !f10 ){
        v.emplace_back(i,0,j,1 );
      }
      if( !f11 ){
        v.emplace_back(i,0,j,0 );
      }
    }
  }

  if(lastsize!=-1 && (int)v.size() == lastsize ){
    return mem;
  }
  lastsize=v.size();
  
  return mem  = sat2( n, v );
}

double solve(){
  for(int i=0;i<m;i++)
    for(int j=0;j<(1<<m);j++)
      for(int k=0;k<m;k++)
        dp[i][j][k]=1e9;

  double maxm=0,mini=1e9;

  if(m==1)mini=0;
  
  for(int i=0;i<m;i++){
    dp[i][(1<<i)][i]=0;
    for(int bit=0;bit<(1<<m);bit++){
      for(int pos=0;pos<m;pos++){
        for(int to=0;to<m;to++){
          double dx=cx[pos]-cx[to];
          double dy=cy[pos]-cy[to];
          double cost=sqrt(dx*dx+dy*dy);
          int nbit=bit|(1<<to);
          dp[i][nbit][to]=min(dp[i][nbit][to],dp[i][bit][pos]+cost);

          maxm=max( maxm , dp[i][nbit][to] + 2000 );
          if(nbit==(1<<m)-1){
            mini=min( mini, dp[i][nbit][to]  );
          }
          
        }
      }
    }
  }
  
  double left=mini,right=maxm,mid;
  for(int i=0;i<50;i++){
    mid=(left+right)*0.5;
    if( check(mid) ){
      exf=1;
      right=mid;
    }    else {
      exf=0;
      left=mid;
    }
  }
  return left;
}

int main(){
  cin>>n>>m;
  for(int i=0;i<n;i++){
    cin>>ax[i]>>ay[i]>>bx[i]>>by[i];
  }
  for(int i=0;i<m;i++){
    cin>>cx[i]>>cy[i];
  }
  printf("%.10f\n",solve());
  return 0;
}
accuracy: 0.35555555555555557
time_ms: 570
memory_kb: 66800
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct data{
	int bit,v;
	double cost;
	data(){}
	data(int bb,int vv,double cc){
		bit=bb;
		v=vv;
		cost=cc;
	}
	bool operator<(const data &d)const{
		return d.cost<cost;
	}
};

int n,m;
P za[201][2];
P factory[15];
double dist[1<<15][15];
double dp[15][15];
double stf[201][2][15];

struct graph_scc{
	int V;
	vector<int> G[501];
	vector<int> rG[501];
	vector<int> vs;
	bool used[501];
	int cmp[501];
	void init(int n){
		V=n;
		for(int i=0;i<V;i++){
			G[i].clear();
			rG[i].clear();
		}
		vs.clear();
		memset(cmp,0,sizeof(cmp));
	}
	void add_edge(int from,int to){
		G[from].push_back(to);
		rG[to].push_back(from);
	}

	void dfs(int v){
		used[v]=true;
		for(int i=0;i<G[v].size();i++){
			if(!used[G[v][i]])dfs(G[v][i]);
		}
		vs.push_back(v);
	}
	void rdfs(int v,int k){
		used[v]=true;
		cmp[v]=k;
		for(int i=0;i<rG[v].size();i++){
			if(!used[rG[v][i]])rdfs(rG[v][i],k);
		}
	}

	int scc(){
		memset(used,0,sizeof(used));
		vs.clear();
		for(int v=0;v<V;v++){
			if(!used[v])dfs(v);
		}
		memset(used,0,sizeof(used));
		int k=0;
		for(int i=vs.size()-1;i>=0;i--){
			if(!used[vs[i]]){
				rdfs(vs[i],k++);
			}
		}
		return k;
	}
};

graph_scc sc;

bool C(double v){
	sc.init(n*2);
	for(int i=0;i<n;i++){
		for(int j=0;j<2;j++){
			for(int k=i+1;k<n;k++){
				for(int l=0;l<2;l++){
					bool flag=false;
					for(int a=0;a<m;a++){
						for(int b=0;b<m;b++){
							double diss=stf[i][j][a];
							diss+=stf[k][l][b];
							diss+=dp[a][b];
							if(diss<=v)flag=true;
						}
					}
					if(!flag){
						sc.add_edge(i+j*n,k+(1-l)*n);
						sc.add_edge(k+l*n,i+(1-j)*n);
					}
				}
			}
		}
	}
	int k=sc.scc();
	for(int i=0;i<n;i++){
		if(sc.cmp[i]==sc.cmp[i+n])return false;
	}
	return true;
}

int main(void){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d%d%d%d",&za[i][0].first,&za[i][0].second,&za[i][1].first,&za[i][1].second);
	}
	for(int i=0;i<m;i++){
		scanf("%d%d",&factory[i].first,&factory[i].second);
	}
	for(int i=0;i<m;i++){
		for(int j=0;j<(1<<m);j++){
			for(int k=0;k<15;k++){
				dist[j][k]=1e9;
			}
		}
		dist[(1<<i)][i]=0.0;
		priority_queue<data> que;
		que.push(data(1<<i,i,0.0));
		while(que.size()){
			data d=que.top();
			que.pop();
			if(dist[d.bit][d.v]<d.cost)continue;
			for(int j=0;j<m;j++){
				int valx=(factory[j].first-factory[d.v].first);
				int valy=(factory[j].second-factory[d.v].second);
				double ncost=sqrt(valx*valx+valy*valy)+d.cost;
				if(dist[d.bit|(1<<j)][j]>ncost){
					dist[d.bit|(1<<j)][j]=ncost;
					que.push(data(d.bit|(1<<j),j,ncost));
				}
			}
		}
		for(int j=0;j<m;j++){
			dp[i][j]=dist[(1<<m)-1][j];
		}
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<2;j++){
			for(int k=0;k<m;k++){
				int valx=(za[i][j].first-factory[k].first);
				int valy=(za[i][j].second-factory[k].second);
				stf[i][j][k]=sqrt(valx*valx+valy*valy);
			}
		}
	}
	double l=0.0,r=114514.0;
	for(int i=0;i<50;i++){
		double mid=(l+r)/2.0;
		if(C(mid))r=mid;
		else l=mid;
	}
	printf("%.9f\n",r);
	return 0;
}
accuracy: 1
time_ms: 1210
memory_kb: 12944
final_rank: 8

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

using namespace std;

struct StronglyConnectedComponents
{
  vector< vector< int > > gg, rg;
  vector< pair< int, int > > edges;
  vector< int > comp, order, used;

  StronglyConnectedComponents(size_t v) : gg(v), rg(v), comp(v, -1), used(v, 0) {}

  void add_edge(int x, int y)
  {
    gg[x].push_back(y);
    rg[y].push_back(x);
    edges.emplace_back(x, y);
  }

  int operator[](int k)
  {
    return (comp[k]);
  }

  void dfs(int idx)
  {
    if(used[idx]) return;
    used[idx] = true;
    for(int to : gg[idx]) dfs(to);
    order.push_back(idx);
  }

  void rdfs(int idx, int cnt)
  {
    if(comp[idx] != -1) return;
    comp[idx] = cnt;
    for(int to : rg[idx]) rdfs(to, cnt);
  }

  void build(vector< vector< int > > &t)
  {
    for(int i = 0; i < gg.size(); i++) dfs(i);
    reverse(begin(order), end(order));
    int ptr = 0;
    for(int i : order) if(comp[i] == -1) rdfs(i, ptr), ptr++;

    t.resize(ptr);
    set< pair< int, int > > connect;
    for(auto &e : edges) {
      int x = comp[e.first], y = comp[e.second];
      if(x == y) continue;
      if(connect.count({x, y})) continue;
      t[x].push_back(y);
      connect.emplace(x, y);
    }
  }
};

int N, M;
int A[200][2], B[200][2];
int X[15], Y[15];
double g[200][2][200][2];

int main()
{
  cin >> N >> M;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < 2; j++) {
      cin >> A[i][j] >> B[i][j];
    }
  }
  for(int i = 0; i < M; i++) {
    cin >> X[i] >> Y[i];
  }

  fill_n(***g, 200 * 2 * 200 * 2, 1e9);
  for(int i = 0; i < M; i++) {
    vector< vector< double > > dp(M, vector< double >(1 << M, 1e9));
    dp[i][1 << i] = 0.0;
    for(int j = 0; j < (1 << M); j++) {
      for(int k = 0; k < M; k++) {
        for(int l = 0; l < M; l++) {
          dp[l][j | (1 << l)] = min(dp[l][j | (1 << l)], dp[k][j] + sqrt(pow(X[k] - X[l], 2) + pow(Y[k] - Y[l], 2)));
        }
      }
    }
    for(int z = 0; z < M; z++) {
      for(int j = 0; j < N; j++) {
        for(int k = 0; k < 2; k++) {
          for(int l = 0; l < N; l++) {
            for(int m = 0; m < 2; m++) {
              double latte = sqrt(pow(A[j][k] - X[i], 2) + pow(B[j][k] - Y[i], 2));
              double malta = sqrt(pow(A[l][m] - X[z], 2) + pow(B[l][m] - Y[z], 2));
              g[j][k][l][m] = min(g[j][k][l][m], latte + malta + dp[z].back());
            }
          }
        }
      }
    }
  }

  auto check = [&](double dist)
  {
    StronglyConnectedComponents scc(N + N);
    for(int i = 0; i < N; i++) {
      for(int j = i + 1; j < N; j++) {
        bool b1 = g[i][0][j][0] > dist;
        bool b2 = g[i][0][j][1] > dist;
        bool b3 = g[i][1][j][0] > dist;
        bool b4 = g[i][1][j][1] > dist;
        if(b1) scc.add_edge(i << 1, (j << 1) | 1), scc.add_edge(j << 1, (i << 1) | 1);
        if(b2) scc.add_edge(i << 1, j << 1), scc.add_edge((j << 1) | 1, (i << 1) | 1);
        if(b3) scc.add_edge((i << 1) | 1, (j << 1) | 1), scc.add_edge(j << 1, i << 1);
        if(b4) scc.add_edge((i << 1) | 1, j << 1), scc.add_edge((j << 1) | 1, i << 1);
      }
    }
    vector< vector< int > > g;
    scc.build(g);
    for(int i = 0; i < N; i += 2) if(scc[i] == scc[i + 1]) return (false);
    return (true);
  };


  double low = 0, high = 1e6;
  for(int i = 0; i < 40; i++) {
    double mid = (low + high) * 0.5;
    if(check(mid)) high = mid;
    else low = mid;
  }

  cout << fixed << setprecision(10) << high << endl;
}
accuracy: 1
time_ms: 760
memory_kb: 8320
final_rank: 4

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

using namespace std;

struct StronglyConnectedComponents
{
  vector< vector< int > > gg, rg;
  vector< pair< int, int > > edges;
  vector< int > comp, order, used;

  StronglyConnectedComponents(size_t v) : gg(v), rg(v), comp(v, -1), used(v, 0) {}

  void add_edge(int x, int y)
  {
    gg[x].push_back(y);
    rg[y].push_back(x);
    edges.emplace_back(x, y);
  }

  int operator[](int k)
  {
    return (comp[k]);
  }

  void dfs(int idx)
  {
    if(used[idx]) return;
    used[idx] = true;
    for(int to : gg[idx]) dfs(to);
    order.push_back(idx);
  }

  void rdfs(int idx, int cnt)
  {
    if(comp[idx] != -1) return;
    comp[idx] = cnt;
    for(int to : rg[idx]) rdfs(to, cnt);
  }

  void build(vector< vector< int > > &t)
  {
    for(int i = 0; i < gg.size(); i++) dfs(i);
    reverse(begin(order), end(order));
    int ptr = 0;
    for(int i : order) if(comp[i] == -1) rdfs(i, ptr), ptr++;

    t.resize(ptr);
    set< pair< int, int > > connect;
    for(auto &e : edges) {
      int x = comp[e.first], y = comp[e.second];
      if(x == y) continue;
      if(connect.count({x, y})) continue;
      t[x].push_back(y);
      connect.emplace(x, y);
    }
  }
};

int N, M;
int A[200][2], B[200][2];
int X[15], Y[15];
double g[200][2][200][2];

int main()
{
  cin >> N >> M;
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < 2; j++) {
      cin >> A[i][j] >> B[i][j];
    }
  }
  for(int i = 0; i < M; i++) {
    cin >> X[i] >> Y[i];
  }

  fill_n(***g, 200 * 2 * 200 * 2, 1e9);
  for(int i = 0; i < M; i++) {
    vector< vector< double > > dp(M, vector< double >(1 << M, 1e9));
    dp[i][1 << i] = 0.0;
    for(int j = 0; j < (1 << M); j++) {
      for(int k = 0; k < M; k++) {
        for(int l = 0; l < M; l++) {
          dp[l][j | (1 << l)] = min(dp[l][j | (1 << l)], dp[k][j] + sqrt(pow(X[k] - X[l], 2) + pow(Y[k] - Y[l], 2)));
        }
      }
    }
    for(int z = 0; z < M; z++) {
      for(int j = 0; j < N; j++) {
        for(int k = 0; k < 2; k++) {
          for(int l = 0; l < N; l++) {
            for(int m = 0; m < 2; m++) {
              double latte = sqrt(pow(A[j][k] - X[i], 2) + pow(B[j][k] - Y[i], 2));
              double malta = sqrt(pow(A[l][m] - X[z], 2) + pow(B[l][m] - Y[z], 2));
              g[j][k][l][m] = min(g[j][k][l][m], latte + malta + dp[z].back());
            }
          }
        }
      }
    }
  }

  auto check = [&](double dist)
  {
    StronglyConnectedComponents scc(N + N);
    for(int i = 0; i < N; i++) {
      for(int j = i + 1; j < N; j++) {
        bool b1 = g[i][0][j][0] > dist;
        bool b2 = g[i][0][j][1] > dist;
        bool b3 = g[i][1][j][0] > dist;
        bool b4 = g[i][1][j][1] > dist;
        if(b1) scc.add_edge(i << 1, (j << 1) | 1), scc.add_edge(j << 1, (i << 1) | 1);
        if(b2) scc.add_edge(i << 1, j << 1), scc.add_edge((j << 1) | 1, (i << 1) | 1);
        if(b3) scc.add_edge((i << 1) | 1, (j << 1) | 1), scc.add_edge(j << 1, i << 1);
        if(b4) scc.add_edge((i << 1) | 1, j << 1), scc.add_edge((j << 1) | 1, i << 1);
      }
    }
    vector< vector< int > > g;
    scc.build(g);
    for(int i = 0; i < N; i += 2) if(scc[i] == scc[i + 1]) return (false);
    return (true);
  };


  double low = 0, high = 1e9;
  for(int i = 0; i < 100; i++) {
    double mid = (low + high) * 0.5;
    if(check(mid)) high = mid;
    else low = mid;
  }

  cout << fixed << setprecision(10) << high << endl;
}
accuracy: 1
time_ms: 890
memory_kb: 8336
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define REP(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) REP(i,0,n)
typedef pair<double,double> P;
#define N 1001
double d[1<<15][15][15];
vector<int> G[N],rG[N],g;
bool u[N];
int n,cmp[N];
  
void add_edge(int x,int y){G[x].push_back(y);rG[y].push_back(x);}
void dfs(int x){u[x]=1;rep(i,G[x].size())if(!u[G[x][i]])dfs(G[x][i]);g.push_back(x);} 
void rdfs(int x,int k){u[x]=1;cmp[x]=k;rep(i,rG[x].size())if(!u[rG[x][i]])rdfs(rG[x][i],k);}
int scc() {
  memset(u,0,sizeof(u));g.clear();rep(i,n)if(!u[i])dfs(i);memset(u,0,sizeof(u));
  int k=0;rrep(i,g.size())if(!u[g[i]])rdfs(g[i],k++);return k;
}
void init() {
  rep(i,n) G[i].clear(),rG[i].clear();
  g.clear();
}
int rev(int x) {return (x+n/2)%n;}
int two_sat(vector<P> v) {
  init();
  rep(i,v.size()) {
    add_edge(v[i].F,rev(v[i].S));
    add_edge(v[i].S,rev(v[i].F));
  }
  scc();
  rep(i,n/2) {
    if(cmp[i]==cmp[i+n/2]) return 0;
  }
  return 1;
}
double D(P a,P b) {
  return sqrt((a.F-b.F)*(a.F-b.F)+(a.S-b.S)*(a.S-b.S));
}

int main() {
  int m;
  cin >> n >> m;
  P a[n][2],b[m];
  rep(i,n)rep(j,2) cin >> a[i][j].F >> a[i][j].S;
  rep(i,m) cin >> b[i].F >> b[i].S;
  rep(t,1<<m)rep(i,m)rep(j,m) d[t][i][j]=1<<30;
  rep(k,m) {
    d[1<<k][k][k]=0;
    rep(t,1<<m) {
      rep(i,m) {
        if(!(t&(1<<i))) continue;
        rep(j,m) {
          if(!(t&(1<<j))) d[t|(1<<j)][k][j]=min(d[t|(1<<j)][k][j],d[t][k][i]+D(b[i],b[j]));
        }
      }
    }
  }
  double c[n][n][4];
  n*=2;
  rep(i,n/2) {
    REP(j,i+1,n/2) {
      rep(k,4) c[i][j][k]=1<<30;
      rep(k,m)rep(l,m)rep(s,2)rep(t,2)c[i][j][s+t*2]=min(c[i][j][s+t*2],D(a[i][s],b[k])+d[(1<<m)-1][k][l]+D(b[l],a[j][t]));
    }
  }
  double l=0,r=10000;
  rep(t,50) {
    double mid=(l+r)/2;
    vector<P> v;
    rep(i,n/2) {
      REP(j,i+1,n/2) {
        if(c[i][j][0]>mid) v.push_back(P(i,j));
        if(c[i][j][1]>mid) v.push_back(P(rev(i),j));
        if(c[i][j][2]>mid) v.push_back(P(i,rev(j)));
        if(c[i][j][3]>mid) v.push_back(P(rev(i),rev(j)));
      }
    }
    if(two_sat(v)) r=mid;
    else l=mid;
  }
  printf("%.10f\n",l);
  return 0;
}
accuracy: 1
time_ms: 370
memory_kb: 66560
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct data{
	int bit,v;
	double cost;
	data(){}
	data(int bb,int vv,double cc){
		bit=bb;
		v=vv;
		cost=cc;
	}
	bool operator<(const data &d)const{
		return d.cost<cost;
	}
};

int n,m;
P za[201][2];
P factory[15];
double dist[1<<15][15];
double dp[15][15];
double stf[201][2][15];

struct graph_scc{
	int V;
	vector<int> G[501];
	vector<int> rG[501];
	vector<int> vs;
	bool used[501];
	int cmp[501];
	void init(int n){
		V=n;
		for(int i=0;i<V;i++){
			G[i].clear();
			rG[i].clear();
		}
		vs.clear();
		memset(cmp,0,sizeof(cmp));
	}
	void add_edge(int from,int to){
		G[from].push_back(to);
		rG[to].push_back(from);
	}

	void dfs(int v){
		used[v]=true;
		for(int i=0;i<G[v].size();i++){
			if(!used[G[v][i]])dfs(G[v][i]);
		}
		vs.push_back(v);
	}
	void rdfs(int v,int k){
		used[v]=true;
		cmp[v]=k;
		for(int i=0;i<rG[v].size();i++){
			if(!used[rG[v][i]])rdfs(rG[v][i],k);
		}
	}

	int scc(){
		memset(used,0,sizeof(used));
		vs.clear();
		for(int v=0;v<V;v++){
			if(!used[v])dfs(v);
		}
		memset(used,0,sizeof(used));
		int k=0;
		for(int i=vs.size()-1;i>=0;i--){
			if(!used[vs[i]]){
				rdfs(vs[i],k++);
			}
		}
		return k;
	}
};

graph_scc sc;

bool C(double v){
	sc.init(n*2);
	for(int i=0;i<n;i++){
		for(int j=0;j<2;j++){
			for(int k=i+1;k<n;k++){
				for(int l=0;l<2;l++){
					bool flag=false;
					for(int a=0;a<m;a++){
						for(int b=0;b<m;b++){
							double diss=stf[i][j][a];
							diss+=stf[k][l][b];
							diss+=dp[a][b];
							if(diss<=v)flag=true;
						}
					}
					if(!flag){
						sc.add_edge(i+j*n,k+(1-l)*n);
						sc.add_edge(k+l*n,i+(1-j)*n);
					}
				}
			}
		}
	}
	int k=sc.scc();
	for(int i=0;i<n;i++){
		if(sc.cmp[i]==sc.cmp[i+n])return false;
	}
	return true;
}

int main(void){
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d%d%d%d",&za[i][0].first,&za[i][0].second,&za[i][1].first,&za[i][1].second);
	}
	for(int i=0;i<m;i++){
		scanf("%d%d",&factory[i].first,&factory[i].second);
	}
	for(int i=0;i<m;i++){
		for(int j=0;j<(1<<m);j++){
			for(int k=0;k<15;k++){
				dist[j][k]=1e9;
			}
		}
		dist[(1<<i)][i]=0.0;
		priority_queue<data> que;
		que.push(data(1<<i,i,0.0));
		while(que.size()){
			data d=que.top();
			que.pop();
			if(dist[d.bit][d.v]<d.cost)continue;
			for(int j=0;j<m;j++){
				int valx=(factory[j].first-factory[d.v].first);
				int valy=(factory[j].second-factory[d.v].second);
				double ncost=sqrt(valx*valx+valy*valy)+d.cost;
				if(dist[d.bit|(1<<j)][j]>ncost){
					dist[d.bit|(1<<j)][j]=ncost;
					que.push(data(d.bit|(1<<j),j,ncost));
				}
			}
		}
		for(int j=0;j<m;j++){
			dp[i][j]=dist[(1<<m)-1][j];
		}
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<2;j++){
			for(int k=0;k<m;k++){
				int valx=(za[i][j].first-factory[k].first);
				int valy=(za[i][j].second-factory[k].second);
				stf[i][j][k]=sqrt(valx*valx+valy*valy);
			}
		}
	}
	double l=0.0,r=114514.0;
	for(int i=0;i<100;i++){
		double mid=(l+r)/2.0;
		if(C(mid))r=mid;
		else l=mid;
	}
	printf("%.9f\n",r);
	return 0;
}
accuracy: 1
time_ms: 1880
memory_kb: 13012
final_rank: 11

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

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

typedef complex<double>Point;

int N,M;
Point A[222][2];

const double INF=1e18;
double dp[15][15][1<<15];
Point P[15];


namespace SCC{
    void visit(const vector<vector<int>>&G,vector<int>&vs,vector<int>&used,int v){
        used[v]=true;
        for(auto u:G[v]){
            if(!used[u])visit(G,vs,used,u);
        }
        vs.push_back(v);
    }

    void visit2(const vector<vector<int>>&T,vector<int>&used,vector<int>&comp,vector<int>&vec,int k,int v){
        comp[v]=k;
        used[v]=true;
        vec.push_back(v);

        for(auto u:T[v]){
            if(!used[u])visit2(T,used,comp,vec,k,u);
        }
    }

   void decompose(const vector<vector<int>>&G,vector<vector<int>>&H,vector<int>&comp){
        vector<vector<int>>T(G.size());
        for(int i=0;i<G.size();i++){
            for(auto v:G[i]){
                T[v].push_back(i);
            }
        }
        comp.resize(G.size());

        vector<int>vs(G.size());
        vector<int>used(G.size());
        for(int i=0;i<G.size();i++){
            if(!used[i])visit(G,vs,used,i);
        }
        reverse(vs.begin(),vs.end());
        fill(used.begin(),used.end(),0);

        int K=0;
        vector<vector<int>>S;
        for(auto v:vs){
            if(!used[v]){
                S.push_back(vector<int>());
                visit2(T,used,comp,S.back(),K++,v);
            }
        }

        H.resize(K);
        fill(used.begin(),used.end(),0);
        for(int i=0;i<K;i++){
            for(auto v:S[i]){
                for(auto u:G[v]){
                    if(used[comp[u]]||comp[v]==comp[u])continue;
                    used[comp[u]]=true;
                    H[comp[v]].push_back(comp[u]);
                }
            }
            for(auto v:H[i])used[v]=false;
        }

    }
}


double dist[200][2][200][2];

bool C(double d){
    vector<vint> G(2*N);
    rep(i,N){
        rep(j,N){
            if(i==j)continue;
            rep(k,2){
                rep(l,2){
                    if(dist[i][k][j][l]>d)G[i*2+k].pb(j*2+1-l),G[j*2+l].pb(i*2+1-k);
                }
            }
        }
    }

    vector<vint>H;
    vint comp;
    SCC::decompose(G,H,comp);

    rep(i,N)if(comp[i*2]==comp[i*2+1])return false;
    return true;
}

signed main(){
    cin>>N>>M;
    rep(i,N){
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        A[i][0]=Point(a,b);
        A[i][1]=Point(c,d);
    }


    rep(i,M){
        int a,b;
        cin>>a>>b;
        P[i]=Point(a,b);
    }

    fill_n(**dp,15*15*(1<<15),INF);

    rep(s,M){
        dp[s][s][1<<s]=0;

        rep(b,1<<M){
            rep(v,M){
                rep(u,M){
                    if(b>>u&1)continue;
                    chmin(dp[s][u][b|(1<<u)],dp[s][v][b]+abs(P[v]-P[u]));
                }
            }
        }
    }

    rep(i,N){
        rep(j,N){
            rep(k,2){
                rep(l,2){
                    double mi=INF;
                    rep(v,M)rep(u,M)chmin(mi,abs(P[v]-A[i][k])+dp[v][u][(1<<M)-1]+abs(A[j][l]-P[u]));
                    dist[i][k][j][l]=mi;
                }
            }
        }
    }


    double lb=0.0,ub=1e6;
    rep(i,50){
        double mid=(ub+lb)/2;
        if(C(mid))ub=mid;
        else lb=mid;
    }

    printf("%.20f\n",ub);
    return 0;

}
accuracy: 1
time_ms: 1330
memory_kb: 68412
final_rank: 12