Problem:
Problem C:
Nagashi Soumen
Mr. Natsume, the captain of a baseball club, decided to hold a
nagashi-soumen
party. He first planned
to put a flume at the arena, and let members stand by the side of the flume to eat soumen. But they are
so weird that they adhere to each special position, and refused to move to the side of the flume. They
requested Mr. Natsume to have the flumes go through their special positions. As they never changed their
minds easily, Mr. Natsume tried to rearrange flumes in order to fulfill their requests.
As a caretaker of the baseball club, you are to help Mr. Natsume arrange the flumes. Here are the rules
on the arrangement:
each flume can begin and end at arbitrary points. Also it can be curved at any point in any direction,
       but cannot have any branches nor merge with another flume;
each flume needs to be placed so that its height strictly decreases as it goes, otherwise soumen does
       not flow;
Mr. Natsume cannot make more than
K
flumes since he has only K machines for water-sliders; and
needless to say, flumes must go through all the special positions so that every member can eat
       soumen.
In addition, to save the cost, you want to arrange flumes so that the total length is as small as possible.
What is the minimum total length of all flumes?
Input
Input consists of multiple data sets. Each data set follows the format below:
N K
x
1
y
1
z
1
...
x
N
y
N
z
N
N
(1 ≤
N
≤ 100) represents the number of attendants,
K
(1 ≤
K
≤ 4) represents the number of available
flumes, and
x
i
,
y
i
,
z
i
(-100 ≤
x
i
,
y
i
,
z
i
≤ 100) represent the
i
-th attendant’s coordinates. All numbers are
integers. The attendants’ coordinates are all different.
A line with two zeros represents the end of input.
Output
For each data set, output in one line the minimum total length of all flumes in Euclidean distance. No
absolute error in your answer may exceed 10
-9
. Output -1 if it is impossible to arrange flumes.
Sample Input
1 1
0 0 0
4 4
0 0 0
1 1 1
2 2 2
3 3 3
3 4
0 0 0
1 1 1
2 2 2
4 1
1 0 1
0 0 0
1 1 0
0 1 -1
5 2
0 0 100
0 0 99
1 0 99
1 0 98
1 0 -100
7 4
71 55 -77
-43 -49 50
73 -22 -89
32 99 -33
64 -22 -25
-76 -1 6
39 4 23
0 0
Output for the Sample Input
0
0
0
-1
200
197.671366737338417

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)

template<class T>
using vi = vector<T>;

template<class T>
using vii = vector<vi<T>>;

template<class T>
using viii = vector<vii<T>>;

struct MCF {
private:
    const long long inf = 1e18;
    vector<long long> dist;       //最短距離(費用)
    vector<int> pv, pe;     //直前の頂点、辺    

public:
    struct edge {
        int to, rev; long long cap, cost;
        edge(int t = 0, int r = 0, long long ca = 0, long long co = 0)
            : to(t), rev(r), cap(ca), cost(co) {}
    };

    struct pii {
        long long d; int v; //最短距離(費用)、頂点番号
        pii(long long d_ = 0, int v_ = 0) : d(d_), v(v_) {}

        bool operator<(const pii& other) const {
            if (d != other.d) return d < other.d;
            return v < other.v;
        }

        bool operator>(const pii& other) const {
            if (d != other.d) return d > other.d;
            return v > other.v;
        }
    };

    int n;
    vector<vector<edge>> to;
    vector<long long> pot;        //ポテンシャル

    MCF(int n_ = 1) : n(n_), to(n_), pot(n_), dist(n_), pv(n_), pe(n_) {}

    void addedge(int u, int v, long long cap, long long cost) {
        int su = (int)to[u].size();
        int sv = (int)to[v].size();
        to[u].push_back({ v, sv, cap, cost });
        to[v].push_back({ u, su, 0, -cost });
    }

    //s->tへ流量fの最小費用流、流せないときは-1
    long long mincostflow(int s, int t, long long f) {
        long long res = 0;
        pot.assign(n, 0);
        while (f) {
            priority_queue<pii, vector<pii>, greater<pii>> pq;
            dist.assign(n, inf);
            dist[s] = 0;
            pq.push({ 0, s });
            while (!pq.empty()) {
                pii elem = pq.top();
                pq.pop();
                if (dist[elem.v] < elem.d) continue;
                int sv = (int)to[elem.v].size();
                for (int i = 0; i < sv; i++) {
                    edge& nv = to[elem.v][i];
                    if (nv.cap == 0 || dist[nv.to] + pot[nv.to] <= dist[elem.v] + pot[elem.v] + nv.cost) continue;
                    dist[nv.to] = dist[elem.v] + pot[elem.v] - pot[nv.to] + nv.cost;
                    pv[nv.to] = elem.v;
                    pe[nv.to] = i;
                    pq.push({ dist[nv.to], nv.to });
                }
            }

            if (dist[t] == inf) return -1; //流せる最小費用流が存在しない

            for (int v = 0; v < n; v++) pot[v] += dist[v];

            long long nf = f;
            for (int v = t; v != s; v = pv[v]) nf = min(nf, to[pv[v]][pe[v]].cap);
            f -= nf;
            res += nf * (pot[t] - pot[s]); //pot[s] = 0で不要だがポテンシャルを明確化する
            for (int v = t; v != s; v = pv[v]) {
                edge& nv = to[pv[v]][pe[v]];
                nv.cap -= nf;
                to[v][nv.rev].cap += nf;
            }
        }
        return res;
    }

    //s->tへ流量fの最小費用流、流せないときは費用と流せなかった流量のペア
    pair<long long, long long> mincostflow_pair(int s, int t, long long f) {
        long long res = 0;
        pot.assign(n, 0);
        while (f) {
            priority_queue<pii, vector<pii>, greater<pii>> pq;
            dist.assign(n, inf);
            dist[s] = 0;
            pq.push({ 0, s });
            while (!pq.empty()) {
                pii elem = pq.top();
                pq.pop();
                if (dist[elem.v] < elem.d) continue;
                int sv = (int)to[elem.v].size();
                for (int i = 0; i < sv; i++) {
                    edge& nv = to[elem.v][i];
                    if (nv.cap == 0 || dist[nv.to] + pot[nv.to] <= dist[elem.v] + pot[elem.v] + nv.cost) continue;
                    dist[nv.to] = dist[elem.v] + pot[elem.v] - pot[nv.to] + nv.cost;
                    pv[nv.to] = elem.v;
                    pe[nv.to] = i;
                    pq.push({ dist[nv.to], nv.to });
                }
            }

            if (dist[t] == inf) return { res, f }; //流せる最小費用流が存在しない

            for (int v = 0; v < n; v++) pot[v] += dist[v];

            long long nf = f;
            for (int v = t; v != s; v = pv[v]) nf = min(nf, to[pv[v]][pe[v]].cap);
            f -= nf;
            res += nf * (pot[t] - pot[s]); //pot[s] = 0で不要だがポテンシャルを明確化する
            for (int v = t; v != s; v = pv[v]) {
                edge& nv = to[pv[v]][pe[v]];
                nv.cap -= nf;
                to[v][nv.rev].cap += nf;
            }
        }
        return { res, f };
    }
};


#include <cmath>
#include <iomanip>

int main()
{
    vi<double> ans;
    int n, k;
    while (cin >> n >> k, n) {
        vi<int> x(n), y(n), z(n);
        rep(i, n) cin >> x[i] >> y[i] >> z[i];

        if (n <= k) {
            ans.push_back(0);
            continue;
        }
        
        MCF mcf(n * 2 + 2);
        int S = n * 2, T = S + 1;
        double mul = 1e11;

        auto f = [&](int i, int j) {
            double dist = sqrt((x[i] - x[j]) * (x[i] - x[j]) 
                            + (y[i] - y[j]) * (y[i] - y[j])
                            + (z[i] - z[j]) * (z[i] - z[j])) * mul;
            return (ll)dist;
        };
        rep(i, n) rep(j, n) {
            if (z[i] <= z[j]) continue;
            mcf.addedge(i, j + n, 1, f(i, j));
        }
        rep(i, n) mcf.addedge(S, i, 1, 0);
        rep(i, n) mcf.addedge(i + n, T, 1, 0);

        double flow = mcf.mincostflow(S, T, n - k);
        if (flow < 0) ans.push_back(-1);
        else ans.push_back(flow / mul);
    }

    for (auto elem : ans) cout << fixed << setprecision(12) << elem << endl;
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3752
final_rank: 8

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


#define NUM 205
long double A = 50000;
#define EPS 0.0000000001

typedef pair<long double,int> P;
struct Edge{
	Edge(int arg_to,int arg_capacity,long double arg_cost,int arg_rev_index){
		to = arg_to;
		capacity = arg_capacity;
		cost = arg_cost;
		rev_index = arg_rev_index;
	}

	int to,capacity,rev_index;
	long double cost;
};

struct Point{

	long double x,y,z;
};

int N,K;
int V; //頂点数
int in_num[205],IN[105],OUT[105];
vector<Edge> G[NUM]; //グラフの隣接リスト表現
long double h[NUM]; //ポテンシャル
long double dist[NUM]; //最短距離
int pre_node[NUM],pre_edge[NUM]; //直前の頂点と辺
Point point[105];


long double calc_dist(Point a,Point b){

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

void add_edge(int from,int to,int capacity,long double cost){
	G[from].push_back(Edge(to,capacity,cost,G[to].size()));
	G[to].push_back(Edge(from,0,-cost,G[from].size()-1));
}

long double min_cost_flow(int source,int sink,int flow){

	long double ret = 0;
	for(int i = 0; i < V; i++)h[i] = 0; //ポテンシャルを0にする
	while(flow > 0){

		priority_queue<P,vector<P>,greater<P>> Q;
		for(int i = 0; i < V; i++)dist[i] = BIG_NUM;
		dist[source] = 0;
		Q.push(P(0,source));

		while(!Q.empty()){
			P p = Q.top();
			Q.pop();
			int node_id = p.second;
			if(dist[node_id] < p.first)continue; //最短でなければSKIP

			for(int i = 0; i < G[node_id].size(); i++){
				Edge &e = G[node_id][i];
				if(e.capacity > 0 && dist[e.to] > dist[node_id]+e.cost+h[node_id]-h[e.to]){

					dist[e.to] = dist[node_id]+e.cost+h[node_id]-h[e.to];

					pre_node[e.to] = node_id;
					pre_edge[e.to] = i;
					Q.push(P(dist[e.to],e.to));
				}
			}
		}

		if(dist[sink] == BIG_NUM){
			//これ以上流せない
			break;
		}

		for(int node_id = 0; node_id < V; node_id++)h[node_id] += dist[node_id];

		int tmp_flow = flow;

		for(int node_id = sink; node_id != source; node_id = pre_node[node_id]){
			tmp_flow = min(tmp_flow,G[pre_node[node_id]][pre_edge[node_id]].capacity);
		}
		flow -= tmp_flow;
		ret += tmp_flow*h[sink];

		for(int node_id = sink; node_id != source; node_id = pre_node[node_id]){

			Edge &e = G[pre_node[node_id]][pre_edge[node_id]];
			e.capacity -= tmp_flow;
			G[node_id][e.rev_index].capacity += tmp_flow;
		}
	}
	return ret;
}

void func(){

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

			in_num[i] = 0;
		}

	int Z;

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

		scanf("%Lf %Lf %d",&point[i].x,&point[i].y,&Z);
		in_num[Z+100]++;
		point[i].z = Z;
	}


	if(N <= K){

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

	for(int i = 0; i <= 200; i++){
		if(in_num[i] > K){

			printf("-1\n");
			return;
		}
	}

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

		G[i].clear();
	}



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

		IN[i] = index++;
	}
	for(int i = 0; i < N; i++){

		OUT[i] = index++;
	}
	int source = index++;
	int sink = index++;

	V = index;

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

		add_edge(source,IN[i],1,0);
		add_edge(IN[i],OUT[i],1,-A);
		add_edge(OUT[i],sink,1,0);
	}

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

			if(point[i].z > point[k].z){
				add_edge(OUT[i],IN[k],1,calc_dist(point[i],point[k]));
			}
		}
	}

	long double ans = min_cost_flow(source,sink,K);

	ans += (long double)N*A;
	printf("%.12Lf\n",ans);
}

int main(){

	while(true){

		scanf("%d %d",&N,&K);
		if(N == 0 && K == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 4036
final_rank: 13

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

using namespace std;

#define int long long

const long double eps = 1e-6;
const long double inf = 1e10;
const long double mxval = 1e6;

#define eq(a, b) (fabs((a)-(b)) < eps)
#define lt(a, b) ((a)-(b) < -eps)

struct PrimalDual {
  struct edge {
    int to, capacity;
    double cost;
    int rev;
    edge(){}
    edge(int to, int capacity, double cost, int rev):to(to), capacity(capacity), cost(cost), rev(rev){}
  };

  vector< vector<edge> > graph;
  vector<long double> potential, mincost;
  vector<int> prevv, preve;
  PrimalDual(int V):graph(V), potential(V), mincost(V), prevv(V), preve(V){}
  void add_edge(int from, int to, int capacity, long double cost) {
    graph[from].push_back(edge(to, capacity, cost, (int)graph[to].size()));
    graph[to].push_back(edge(from, 0, -cost, (int)graph[from].size()-1));
  }
  long double min_cost_flow(int source, int sink, int f) {
    long double res = 0;
    fill(potential.begin(), potential.end(), 0);
    fill(prevv.begin(), prevv.end(), -1);
    fill(preve.begin(), preve.end(), -1);

    typedef pair<long double, int> Pi;
    while(f > 0) {
      priority_queue<Pi, vector<Pi>, greater<Pi> > que;
      fill(mincost.begin(), mincost.end(), inf);
      mincost[source] = 0;
      que.push(Pi(0, source));
      while(!que.empty()) {
	Pi p = que.top(); que.pop();
	int v = p.second;
	if(mincost[v] < p.first) continue;
	for(int i = 0; i < (int)graph[v].size(); i++) {
	  edge& e = graph[v][i];
	  long double dual_cost = mincost[v] + e.cost + potential[v] - potential[e.to];
	  if(e.capacity > 0 && !eq(dual_cost, mincost[e.to]) && dual_cost < mincost[e.to]) {
	    mincost[e.to] = dual_cost;
	    //printf("%lld %.12Lf\n", e.to, mincost[e.to]);
	    prevv[e.to] = v; preve[e.to] = i;
	    que.push(Pi(mincost[e.to], e.to));
	  }
	}
      }

      for(int v = 0; v < (int)graph.size(); v++) potential[v] += mincost[v];

      if(potential[sink] >= 0) break;
      int d = f;
      for(int v = sink; v != source; v = prevv[v]) d = min(d, graph[prevv[v]][preve[v]].capacity);
      //cout<<"OK"<<endl;
      f -= d;

      res += d * potential[sink];
      for(int v = sink; v != source; v = prevv[v]) {
	edge& e = graph[prevv[v]][preve[v]];
	e.capacity -= d;
	graph[v][e.rev].capacity += d;
      }
    }
    return res;
  }
};

long double sq(long double x) {
  return x*x;
}

signed main() {
  int N, K;
  while(scanf("%lld %lld", &N, &K), N || K) {
    vector<int> x(N), y(N), z(N);
    map<int, int> mp;
    for(int i = 0; i < N; ++i) {
      scanf("%lld %lld %lld", &x[i], &y[i], &z[i]);
      mp[z[i]]++;
    }
    if(N <= K) {
      printf("0\n");
      continue;
    }
    bool flag = false;
    for(auto p : mp) {
      if(p.second > K) flag = true;
    }
    if(flag) {
      printf("-1\n");
      continue;
    }

    int s = 2*N, t = s+1, V = t+1;
    PrimalDual graph(V);
    for(int i = 0; i < N; ++i) {
      graph.add_edge(s, i, 1, 0);
      graph.add_edge(i, N+i, 1, -mxval);
      graph.add_edge(N+i, t, 1, 0);
      for(int j = 0; j < N; ++j) {
	if(i == j) continue;
	if(z[i] > z[j]) {
	  long double norm = sq(x[i]-x[j])+sq(y[i]-y[j])+sq(z[i]-z[j]);
	  long double dist = sqrt(norm);
	  graph.add_edge(N+i, j, 1, dist);
	}
      }
    }
    long double res = graph.min_cost_flow(s, t, K);
    printf("%.12Lf\n", res+N*mxval);
  }
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 3580
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
#define pr(...) GET_MACRO(__VA_ARGS__,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__)
#define pr1(a) (#a)<<"="<<(a)
#define pr2(a,b) pr1(a)<<", "<<pr1(b)
#define pr3(a,b,c) pr2(a,b)<<", "<<pr1(c)
#define pr4(a,b,c,d) pr3(a,b,c)<<", "<<pr1(d)
#define pr5(a,b,c,d,e) pr4(a,b,c,d)<<", "<<pr1(e)
#define int long long
#define double long double
using namespace std;
const int N = 100010;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
typedef pair<int,int> P;
typedef long long ll;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
ostream& operator<<(ostream& o,P p){return o<<"("<<p.first<<","<<p.second<<")";}
istream& operator>>(istream& i,P &p){return i>>p.first>>p.second;}
ostream& operator<<(ostream& o,vector<auto> &a){int i=0;for(auto t:a)o<<(i++?" ":"")<<t;return o;}
istream& operator>>(istream& i,vector<auto> &a){for(auto &t:a)i>>t;return i;}
void prArr(auto a,string s=" "){int i=0;for(auto t:a)cout<<(i++?s:"")<<t;cout<<endl;}

/*最小費用流(ワーシャルフロイド使用) O(F|V||E|)*/
class MinCostFlow{
public:
  //辺を表す構造体(行き先、容量、コスト、逆辺)
  typedef double ctype;
  ctype INF = 1LL<<55;

  struct edge{
    int to,cap;
    ctype cost;
    int rev;
    edge();
    edge(int to,int cap,ctype cost,int rev):to(to),cap(cap),cost(cost),rev(rev){}
  };
  
  int V;                          //頂点数
  vector<vector<edge> > G;        //グラフの隣接リスト表現
  vector<ctype> dist;             //最短距離
  vector<int> prevv,preve;        //直前の頂点と辺

  MinCostFlow():V(-1){}
  MinCostFlow(int V):V(V), G(V), dist(V), prevv(V), preve(V){};
  
  // fromからtoへ向かう容量cap、コストcostの辺をグラフに追加する。
  void add_edge(int from,int to,int cap ,ctype cost){
    assert(from>=0 && to >= 0);
    assert(from<V && to<V);
    G[from].push_back((edge){to,cap,cost,(int)G[to].size()});
    G[to].push_back((edge){from,0,-cost,(int)G[from].size()-1});
  }
  
  //sからtへの流量fの最小費用流を求める
  //流せない場合-1を返す
  ctype flow(int s, int t, int f){
    ctype res = 0;

    while(f>0){
      //ベルマンフォード法により,s-t間最短路を求める
      fill(dist.begin(),dist.end(),INF);
      dist[s] = 0;
      bool update = true;
      while(update){
        update = false;
        for(int v=0; v<V ;v++){
          if(dist[v]==INF) continue;
          for(int i=0; i<(int)G[v].size(); i++){
            edge &e = G[v][i];
            if(e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
              if(abs(dist[e.to] - dist[v] - e.cost) < EPS) continue;
              dist[e.to] = dist[v] + e.cost;
              prevv[e.to] = v;
              preve[e.to] = i;
              update = true;
            }
          }
        }
      }

      if(dist[t]==INF) return -1; //これ以上流せない。
    
      //s−t間短路に沿って目一杯流す
      int d = f;
      for(int v=t; v!=s; v=prevv[v]) d = min(d, G[prevv[v]][preve[v]].cap);
      f -= d;
      res += d * dist[t];
      for(int v=t; v!=s; v=prevv[v]){
        edge &e = G[prevv[v]][preve[v]];
        e.cap -= d;
        G[v][e.rev].cap += d;
      }
    }
    return res;
  }
};



signed main(){
  while(1){
  int n,K;
  cin>>n>>K;
  if(n == 0 && K == 0) return 0;
  Min(K,n);
  
  vector<double> X(n),Y(n),Z(n);
  for(int i=0;i<n;i++) cin>>X[i]>>Y[i]>>Z[i];

  MinCostFlow mcf(2 * n + 10);
  const int S = mcf.V-1, T = S - 1;
  
  const double inf = 1e7;
  for(int i=0;i<n;i++) mcf.add_edge(S,i,1,0);
  for(int i=0;i<n;i++) mcf.add_edge(i,n+i,1,-inf);
  for(int i=0;i<n;i++) mcf.add_edge(n+i,T,1,0); 

  auto dis=[&](int i,int j){
    double x = X[i] - X[j];
    double y = Y[i] - Y[j];
    double z = Z[i] - Z[j];
    return sqrt(x * x + y * y + z * z);
  };

  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++){
      if(Z[i] <= Z[j]) continue;
      double d = dis(i,j);
      mcf.add_edge(n + i, j, 1, d);
    }

  double c = mcf.flow(S,T,K);
  if(c == -1) {cout<<-1<<endl;return 0;}
  
  double ans = c + n * inf;
  if(ans >= inf) cout<<-1<<endl;
  else printf("%.10Lf\n",ans);
  
  }
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3772
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T>
vector<T> make_v(size_t a){return vector<T>(a);}
template<typename T>
vector<vector<T> > make_v(size_t a,size_t b){
  return vector<vector<T> >(a,make_v<T>(b));
}
template<typename T>
vector<vector<vector<T> > > make_v(size_t a,size_t b,size_t c){
  return vector<vector<vector<T> > > (a,make_v<T>(b,c));
}

template<typename T,typename V>
typename enable_if<is_class<T>::value==0>::type
fill_v(T &t,const V &v){t=v;}

template<typename T,typename V>
typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t,const V &v){
  for(auto &e:t) fill_v(e,v);
}

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
struct Precision{
  Precision(){
    cout<<fixed<<setprecision(20);
  }
}precision_beet;

signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n,k;
  while(cin>>n>>k,n){
    using T = tuple<Int, Int, Int>;
    vector<T> v;
    map<Int, Int> cnt;
    for(Int i=0;i<n;i++){
      Int x,y,z;
      cin>>x>>y>>z;
      v.emplace_back(z,x,y);
      cnt[z]++;
    }
    Int flg=0;
    for(auto p:cnt){
      if(p.second>k){
	cout<<-1<<endl;
	flg=1;
	break;
      }
    }
    if(flg) continue;
    sort(v.rbegin(),v.rend());
    v.erase(unique(v.begin(),v.end()),v.end());
    assert((Int)v.size()==n);
    
    const double inf = 1e18;
    auto dist=make_v<double>(n,n);
    fill_v(dist,0);
    auto calc=[&](T a,T b){
      if(get<0>(a)==get<0>(b)) return inf;
      double sum=0;
      sum+=(get<0>(a)-get<0>(b))*(get<0>(a)-get<0>(b));
      sum+=(get<1>(a)-get<1>(b))*(get<1>(a)-get<1>(b));
      sum+=(get<2>(a)-get<2>(b))*(get<2>(a)-get<2>(b));
      return sqrt(sum);
    };
    
    for(Int i=0;i<n;i++)
      for(Int j=0;j<n;j++)
	dist[i][j]=calc(v[i],v[j]);

    auto di=[&](Int i,Int j){
      if(min(i,j)<0) return (double)0.;
      return dist[i][j];
    };

    auto dp=make_v<double>(n+1,n+1,n+1);
    fill_v(dp,inf);
    dp[0][0][0]=0;
    
    auto nx=make_v<double>(n+1,n+1,n+1);    
    for(Int i=0;i<n;i++){
      fill_v(nx,inf);
      for(Int a=-1;a<i;a++){
	for(Int b=-1;b<0||b<a;b++){
	  for(Int c=-1;c<0||c<b;c++){
	    if(dp[a+1][b+1][c+1]>=inf) continue;
	    //cout<<i-1<<" "<<a<<" "<<b<<" "<<c<<":"<<dp[a+1][b+1][c+1]<<endl;
	    chmin(nx[a+1][b+1][c+1],dp[a+1][b+1][c+1]+di(i-1,i));
	    chmin(nx[i+0][b+1][c+1],dp[a+1][b+1][c+1]+di(a,i));
	    chmin(nx[i+0][a+1][c+1],dp[a+1][b+1][c+1]+di(b,i));
	    chmin(nx[i+0][a+1][b+1],dp[a+1][b+1][c+1]+di(c,i));
	  }
	}
      }
      swap(dp,nx);
    }
    double ans=inf;
    
    for(Int a=-1;a<n;a++){
      for(Int b=-1;b<0||b<a;b++){
	for(Int c=-1;c<0||c<b;c++){
	  Int s=(a==-1)+(b==-1)+(c==-1);
	  if(k+s>=4) chmin(ans,dp[a+1][b+1][c+1]);
	}
      }
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1820
memory_kb: 19968
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T>
vector<T> make_v(size_t a){return vector<T>(a);}
template<typename T>
vector<vector<T> > make_v(size_t a,size_t b){
  return vector<vector<T> >(a,make_v<T>(b));
}
template<typename T>
vector<vector<vector<T> > > make_v(size_t a,size_t b,size_t c){
  return vector<vector<vector<T> > > (a,make_v<T>(b,c));
}

template<typename T,typename V>
typename enable_if<is_class<T>::value==0>::type
fill_v(T &t,const V &v){t=v;}

template<typename T,typename V>
typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t,const V &v){
  for(auto &e:t) fill_v(e,v);
}

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
struct Precision{
  Precision(){
    cout<<fixed<<setprecision(20);
  }
}precision_beet;

signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n,k;
  while(cin>>n>>k,n){
    using T = tuple<Int, Int, Int>;
    vector<T> v;
    map<Int, Int> cnt;
    for(Int i=0;i<n;i++){
      Int x,y,z;
      cin>>x>>y>>z;
      v.emplace_back(z,x,y);
      cnt[z]++;
    }
    sort(v.rbegin(),v.rend());
    v.erase(unique(v.begin(),v.end()),v.end());
    assert((Int)v.size()==n);
    
    const double inf = 1e18;
    auto dist=make_v<double>(n,n);
    fill_v(dist,0);
    auto calc=[&](T a,T b){
      if(get<0>(a)==get<0>(b)) return inf;
      double sum=0;
      sum+=(get<0>(a)-get<0>(b))*(get<0>(a)-get<0>(b));
      sum+=(get<1>(a)-get<1>(b))*(get<1>(a)-get<1>(b));
      sum+=(get<2>(a)-get<2>(b))*(get<2>(a)-get<2>(b));
      return sqrt(sum);
    };
    
    for(Int i=0;i<n;i++)
      for(Int j=0;j<n;j++)
	dist[i][j]=calc(v[i],v[j]);

    auto di=[&](Int i,Int j){
      if(min(i,j)<0) return (double)0.;
      return dist[i][j];
    };

    auto dp=make_v<double>(n+1,n+1,n+1);
    fill_v(dp,inf);
    dp[0][0][0]=0;
    
    auto nx=make_v<double>(n+1,n+1,n+1);    
    for(Int i=0;i<n;i++){
      fill_v(nx,inf);
      for(Int a=-1;a<i;a++){
	for(Int b=-1;b<0||b<a;b++){
	  for(Int c=-1;c<0||c<b;c++){
	    if(dp[a+1][b+1][c+1]>=inf) continue;
	    //cout<<i-1<<" "<<a<<" "<<b<<" "<<c<<":"<<dp[a+1][b+1][c+1]<<endl;
	    chmin(nx[a+1][b+1][c+1],dp[a+1][b+1][c+1]+di(i-1,i));
	    chmin(nx[i+0][b+1][c+1],dp[a+1][b+1][c+1]+di(a,i));
	    chmin(nx[i+0][a+1][c+1],dp[a+1][b+1][c+1]+di(b,i));
	    chmin(nx[i+0][a+1][b+1],dp[a+1][b+1][c+1]+di(c,i));
	  }
	}
      }
      swap(dp,nx);
    }
    double ans=inf;
    
    for(Int a=-1;a<n;a++){
      for(Int b=-1;b<0||b<a;b++){
	for(Int c=-1;c<0||c<b;c++){
	  Int s=(a==-1)+(b==-1)+(c==-1);
	  if(k+s>=4) chmin(ans,dp[a+1][b+1][c+1]);
	}
      }
    }
    if(ans>inf/2) cout<<-1<<endl; 
    else cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 2480
memory_kb: 20072
final_rank: 16

code_snippet: #include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

struct MinimumCostFlow {
	using Flow = int;
	using Cost = double;
	const Cost kInfCost = INF;
	struct Edge {
		int to, rev;
		Flow cap;
		Cost cost;
		Edge() {}
		Edge(int to, int rev, Flow cap, Cost cost) :to(to), rev(rev), cap(cap), cost(cost) {}
	};
	int n;
	vector<vector<Edge>> g;
	vector<Cost> dist;
	vector<int> prevv, preve;
	MinimumCostFlow(int n) :n(n), g(n), dist(n), prevv(n), preve(n) {}
	void addArc(int from, int to, Flow cap, Cost cost) {
		g[from].emplace_back(to, (int)g[to].size(), cap, cost);
		g[to].emplace_back(from, (int)g[from].size() - 1, Flow(), -cost);
	}
	// s??????t????????????f???????°??????¨???
	// ??????????????´?????? kInfCost
	Cost minimumCostFlow(int s, int t, Flow f) {
		Cost total = Cost();
		while (f > 0) {
			// Bellman-Ford
			fill(dist.begin(), dist.end(), kInfCost);
			dist[s] = 0;
			bool update = true;
			while (update) {
				update = false;
				for (int v = 0; v < n; v++) {
					if (dist[v] == kInfCost)continue;
					for (int i = 0; i < g[v].size(); i++) {
						Edge &e = g[v][i];
						if (e.cap > Flow() && dist[e.to] > dist[v] + e.cost) {
							dist[e.to] = dist[v] + e.cost;
							prevv[e.to] = v;
							preve[e.to] = i;
							update = true;
						}
					}
				}
			}
			// ????????\???????????????
			if (dist[t] == kInfCost)
				return kInfCost;
			// ?????????????????£??????????????????
			Flow d = f;
			for (int v = t; v != s; v = prevv[v])
				d = min(d, g[prevv[v]][preve[v]].cap);
			f -= d;
			total += dist[t] * d;
			for (int v = t; v != s; v = prevv[v]) {
				Edge &e = g[prevv[v]][preve[v]];
				e.cap -= d;
				g[v][e.rev].cap += d;
			}
		}
		return total;
	}
};

template<class T, class ...Tail>
void tiedSort(vector<T> &a, vector<Tail>&... tail) {
	int n = a.size();
	using S = tuple<T, Tail...>;
	vector<S> s(n);
	for (int i = 0; i < n; i++)
		s[i] = make_tuple(a[i], tail[i]...);
	sort(s.begin(), s.end());
	for (int i = 0; i < n; i++)
		tie(a[i], tail[i]...) = s[i];
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(10);
	for (int N, K; cin >> N >> K&&N;) {
		vector<int> x(N), y(N), z(N); rep(i, 0, N) {
			cin >> x[i] >> y[i] >> z[i];
		}
		MinimumCostFlow mcf(N + N + 2);
		int s = mcf.n - 2, t = s + 1;
		auto distance = [&](int i, int j) {
			return sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]) + (z[i] - z[j])*(z[i] - z[j]));
		};
		tiedSort(z, x, y);
		rep(i, 0, N)rep(j, 0, i) {
			if (z[i] != z[j])
				mcf.addArc(i, j + N, 1, distance(i, j));
		}
		rep(i, 0, N) {
			mcf.addArc(s, i, 1, 0);
			mcf.addArc(i + N, t, 1, 0);
		}
		auto res = mcf.minimumCostFlow(s, t, max(0, N - K));
		cout << (res == mcf.kInfCost ? -1 : res) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 3500
final_rank: 10

code_snippet: #include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

struct MinimumCostFlow {
	using Flow = int;
	using Cost = double;
	const Cost kInfCost = INF;
	struct Edge {
		int to, rev;
		Flow cap;
		Cost cost;
		Edge() {}
		Edge(int to, int rev, Flow cap, Cost cost) :to(to), rev(rev), cap(cap), cost(cost) {}
	};
	int n;
	vector<vector<Edge>> g;
	vector<Cost> dist;
	vector<int> prevv, preve;
	MinimumCostFlow(int n) :n(n), g(n), dist(n), prevv(n), preve(n) {}
	void addArc(int from, int to, Flow cap, Cost cost) {
		g[from].emplace_back(to, (int)g[to].size(), cap, cost);
		g[to].emplace_back(from, (int)g[from].size() - 1, Flow(), -cost);
	}
	// s??????t????????????f???????°??????¨???
	// ??????????????´?????? kInfCost
	Cost minimumCostFlow(int s, int t, Flow f) {
		Cost total = Cost();
		while (f > 0) {
			// Bellman-Ford
			fill(dist.begin(), dist.end(), kInfCost);
			dist[s] = 0;
			bool update = true;
			while (update) {
				update = false;
				for (int v = 0; v < n; v++) {
					if (dist[v] == kInfCost)continue;
					for (int i = 0; i < g[v].size(); i++) {
						Edge &e = g[v][i];
						if (e.cap > Flow() && dist[e.to] > dist[v] + e.cost) {
							dist[e.to] = dist[v] + e.cost;
							prevv[e.to] = v;
							preve[e.to] = i;
							update = true;
						}
					}
				}
			}
			// ????????\???????????????
			if (dist[t] == kInfCost)
				return kInfCost;
			// ?????????????????£??????????????????
			Flow d = f;
			for (int v = t; v != s; v = prevv[v])
				d = min(d, g[prevv[v]][preve[v]].cap);
			f -= d;
			total += dist[t] * d;
			for (int v = t; v != s; v = prevv[v]) {
				Edge &e = g[prevv[v]][preve[v]];
				e.cap -= d;
				g[v][e.rev].cap += d;
			}
		}
		return total;
	}
};


signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(10);
	for (int N, K; cin >> N >> K&&N;) {
		vector<int> x(N), y(N), z(N); rep(i, 0, N) {
			cin >> x[i] >> y[i] >> z[i];
		}
		MinimumCostFlow mcf(N + N + 2);
		int s = mcf.n - 2, t = s + 1;
		auto distance = [&](int i, int j) {
			return sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]) + (z[i] - z[j])*(z[i] - z[j]));
		};
		rep(i, 0, N)rep(j, 0, N) {
			if (z[i] >= z[j])continue;
			mcf.addArc(i, j + N, 1, distance(i, j));
		}
		rep(i, 0, N) {
			mcf.addArc(s, i, 1, 0);
			mcf.addArc(i + N, t, 1, 0);
		}
		auto res = mcf.minimumCostFlow(s, t, max(0, N - K));
		cout << (res == mcf.kInfCost ? -1 : res) << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 3520
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <queue>
#include <functional>
#include <map>
using namespace std;
#define doub
const int MAX_V = 100010;
using Capacity = int;
using Cost = double;
const auto inf = numeric_limits<Capacity>::max() / 8;

struct Edge {
	int dst;
	Capacity cap, cap_orig;
	Cost cost;
	int revEdge; bool isRev;
	Edge(int dst, Capacity cap, Cost cost, int revEdge, bool isRev)
		:dst(dst), cap(cap), cap_orig(cap), cost(cost), revEdge(revEdge), isRev(isRev) {
	}
};

struct PrimalDual {
	int n;
	vector<vector<Edge> > g;
	PrimalDual(int n_) : n(n_), g(vector<vector<Edge> >(n_)) {}
	void add_edge(int src, int dst, Capacity cap, Cost cost) { // テヲツ慊嘉・ツ青妥ィツセツコ
		g[src].emplace_back(dst, cap, cost, g[dst].size(), false);
		g[dst].emplace_back(src, 0, -cost, g[src].size() - 1, true);
	}
	Cost solve(int s, int t, int f) {
		Cost res = 0;
		static Cost h[MAX_V], dist[MAX_V];
		static int prevv[MAX_V], preve[MAX_V];
		for(int i = 0; i < n; i++) {
			h[i] = 0;
		}
		while(f > 0) {
			typedef pair<Cost, int> pcv;
			priority_queue<pcv, vector<pcv>, greater<pcv> > q;
			for(int i = 0; i < n; i++) {
				dist[i] = inf;
			}
			dist[s] = 0;
			q.emplace(pcv(0, s));
			while(q.size()) {
				pcv p = q.top(); q.pop();
				int v = p.second;
				if(dist[v] < p.first) continue;
				for(int i = 0; i < g[v].size(); i++) {
					Edge &e = g[v][i];
					if(e.cap > 0 && dist[e.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
						dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
						prevv[e.dst] = v;
						preve[e.dst] = i;
						q.emplace(pcv(dist[e.dst], e.dst));
					}
				}
			}
			if(dist[t] == inf) {
				assert(0);
				return -1;
			}
			for(int v = 0; v < n; v++) {
				h[v] += dist[v];
			}
			// s-t テゥツ鳴禿ヲツ慊?ァツ淞ュティツキツッテ」ツ?ォテヲツイツソテ」ツ?」テ」ツ?ヲテァツ崢ョテ、ツクツ?ヲツ敖ッテヲツオツ?」ツ??
			int d = f;
			for(int v = t; v != s; v = prevv[v]) {
				d = min(d, g[prevv[v]][preve[v]].cap);
			}
			f -= d;
			res += d * h[t];
			for(int v = t; v != s; v = prevv[v]) {
				Edge &e = g[prevv[v]][preve[v]];
				e.cap -= d;
				g[v][e.revEdge].cap += d;
			}
		}
		return res;
	}
	// テヲツオツ?」ツつ古」ツ?淌」ツδ陛」ツδュテ」ツδシ=テ・ツ?ε」ツ??」ツ?ョテ・ツョツケテゥツ??テァツ渉セテ・ツ慊ィテ」ツ?ョテ・ツョツケテゥツ?湘」ツつ津ィツ。ツィテァツ、ツコ
	void view() {
		for(int i = 0; i < g.size(); i++) {
			for(int j = 0; j < g[i].size(); j++) {
				if(!g[i][j].isRev) {
					Edge& e = g[i][j];
					printf("%3d->%3d (flow:%d)\n", i, e.dst, e.cap_orig - e.cap);
				}
			}
		}
	}
};

struct point {
	double x, y, z;
};

double dist(point p1, point p2) {
	p1.x -= p2.x;
	p1.y -= p2.y;
	p1.z -= p2.z;
	return sqrt(p1.x * p1.x + p1.y * p1.y + p1.z * p1.z);
}

const double INF2 = 10000;

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

	int N, K;
	while(cin >> N >> K, N | K) {
		vector<point> ps(N);

		map<int, int> m;
		for(int i = 0; i < N; i++) {
			cin >> ps[i].x >> ps[i].y >> ps[i].z;
			m[ps[i].z]++;
		}

		bool flag = false;
		for(auto& p : m) {
			if(p.second > K) {
				printf("-1\n");
				flag = true;
				break;
			}
		}
		if(flag) continue;

		vector<int> in(N), out(N);
		for(int i = 0; i < N; i++) {
			in[i] = 2 * i;
			out[i] = in[i] + 1;
		}

		PrimalDual pd(2 * N + 2);
		int S = 2 * N, T = S + 1;

		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				if(ps[i].z <= ps[j].z) continue;
				pd.add_edge(out[i], in[j], 1, dist(ps[i], ps[j]));
			}
			pd.add_edge(in[i], out[i], 1, -INF2);
			pd.add_edge(out[i], T, 1, 0);
			pd.add_edge(S, in[i], 1, 0);
		}
		pd.add_edge(S, T, 100000, 0);

		double res = pd.solve(S, T, K);
		//pd.view();
		printf("%.10f\n", res + N  * INF2);
	}
}
accuracy: 1
time_ms: 80
memory_kb: 3764
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <queue>
#include <functional>
#include <map>
using namespace std;
#define doub
const int MAX_V = 100010;
using Capacity = int;
using Cost = double;
const auto inf = numeric_limits<Capacity>::max() / 8;

struct Edge {
	int dst;
	Capacity cap, cap_orig;
	Cost cost;
	int revEdge; bool isRev;
	Edge(int dst, Capacity cap, Cost cost, int revEdge, bool isRev)
		:dst(dst), cap(cap), cap_orig(cap), cost(cost), revEdge(revEdge), isRev(isRev) {
	}
};

struct PrimalDual {
	int n;
	vector<vector<Edge> > g;
	PrimalDual(int n_) : n(n_), g(vector<vector<Edge> >(n_)) {}
	void add_edge(int src, int dst, Capacity cap, Cost cost) { // ?????????
		g[src].emplace_back(dst, cap, cost, g[dst].size(), false);
		g[dst].emplace_back(src, 0, -cost, g[src].size() - 1, true);
	}
	Cost solve(int s, int t, int f) {
		Cost res = 0;
		static Cost h[MAX_V], dist[MAX_V];
		static int prevv[MAX_V], preve[MAX_V];
		for(int i = 0; i < n; i++) {
			h[i] = 0;
		}
		while(f > 0) {
			typedef pair<Cost, int> pcv;
			priority_queue<pcv, vector<pcv>, greater<pcv> > q;
			for(int i = 0; i < n; i++) {
				dist[i] = inf;
			}
			dist[s] = 0;
			q.emplace(pcv(0, s));
			while(q.size()) {
				pcv p = q.top(); q.pop();
				int v = p.second;
				if(dist[v] < p.first) continue;
				for(int i = 0; i < g[v].size(); i++) {
					Edge &e = g[v][i];
					if(e.cap > 0 && dist[e.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
						dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
						prevv[e.dst] = v;
						preve[e.dst] = i;
						q.emplace(pcv(dist[e.dst], e.dst));
					}
				}
			}
			if(dist[t] == inf) {
				assert(0);
				return -1;
			}
			for(int v = 0; v < n; v++) {
				h[v] += dist[v];
			}
			// s-t ????????????????????£??????????????????
			int d = f;
			for(int v = t; v != s; v = prevv[v]) {
				d = min(d, g[prevv[v]][preve[v]].cap);
			}
			f -= d;
			res += d * h[t];
			for(int v = t; v != s; v = prevv[v]) {
				Edge &e = g[prevv[v]][preve[v]];
				e.cap -= d;
				g[v][e.revEdge].cap += d;
			}
		}
		return res;
	}
	// ??????????????????=???????????????-?????¨??????????????¨???
	void view() {
		for(int i = 0; i < g.size(); i++) {
			for(int j = 0; j < g[i].size(); j++) {
				if(!g[i][j].isRev) {
					Edge& e = g[i][j];
					printf("%3d->%3d (flow:%d)\n", i, e.dst, e.cap_orig - e.cap);
				}
			}
		}
	}
};

struct point {
	double x, y, z;
};

double dist(point p1, point p2) {
	p1.x -= p2.x;
	p1.y -= p2.y;
	p1.z -= p2.z;
	return sqrt(p1.x * p1.x + p1.y * p1.y + p1.z * p1.z);
}

const double INF2 = 10000;

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

	int N, K;
	while(cin >> N >> K, N | K) {
		vector<point> ps(N);

		map<int, int> m;
		for(int i = 0; i < N; i++) {
			cin >> ps[i].x >> ps[i].y >> ps[i].z;
			m[ps[i].z]++;
		}

		bool flag = false;
		for(auto& p : m) {
			if(p.second > K) {
				printf("-1\n");
				flag = true;
				break;
			}
		}
		if(flag) continue;

		vector<int> in(N), out(N);
		for(int i = 0; i < N; i++) {
			in[i] = 2 * i;
			out[i] = in[i] + 1;
		}

		PrimalDual pd(2 * N + 2);
		int S = 2 * N, T = S + 1;

		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				if(ps[i].z <= ps[j].z) continue;
				pd.add_edge(out[i], in[j], 1, dist(ps[i], ps[j]));
			}
			pd.add_edge(in[i], out[i], 1, -INF2);
			pd.add_edge(out[i], T, 1, 0);
			pd.add_edge(S, in[i], 1, 0);
		}
		pd.add_edge(S, T, 100000, 0);

		double res = pd.solve(S, T, K);
		//pd.view();
		printf("%.10f\n", res + N  * INF2);
	}
}
accuracy: 1
time_ms: 80
memory_kb: 3664
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <cassert>
#include <queue>
#include <functional>
#include <map>
using namespace std;
#define doub
const int MAX_V = 100010;
using Capacity = int;
using Cost = double;
const auto inf = numeric_limits<Capacity>::max() / 8;

struct Edge {
	int dst;
	Capacity cap, cap_orig;
	Cost cost;
	int revEdge; bool isRev;
	Edge(int dst, Capacity cap, Cost cost, int revEdge, bool isRev)
		:dst(dst), cap(cap), cap_orig(cap), cost(cost), revEdge(revEdge), isRev(isRev) {
	}
};

struct PrimalDual {
	int n;
	vector<vector<Edge> > g;
	PrimalDual(int n_) : n(n_), g(vector<vector<Edge> >(n_)) {}
	void add_edge(int src, int dst, Capacity cap, Cost cost) { // ?????????
		g[src].emplace_back(dst, cap, cost, g[dst].size(), false);
		g[dst].emplace_back(src, 0, -cost, g[src].size() - 1, true);
	}
	Cost solve(int s, int t, int f) {
		Cost res = 0;
		static Cost h[MAX_V], dist[MAX_V];
		static int prevv[MAX_V], preve[MAX_V];
		for(int i = 0; i < n; i++) {
			h[i] = 0;
		}
		while(f > 0) {
			typedef pair<Cost, int> pcv;
			priority_queue<pcv, vector<pcv>, greater<pcv> > q;
			for(int i = 0; i < n; i++) {
				dist[i] = inf;
			}
			dist[s] = 0;
			q.emplace(pcv(0, s));
			while(q.size()) {
				pcv p = q.top(); q.pop();
				int v = p.second;
				if(dist[v] < p.first) continue;
				for(int i = 0; i < g[v].size(); i++) {
					Edge &e = g[v][i];
					if(e.cap > 0 && dist[e.dst] > dist[v] + e.cost + h[v] - h[e.dst]) {
						dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
						prevv[e.dst] = v;
						preve[e.dst] = i;
						q.emplace(pcv(dist[e.dst], e.dst));
					}
				}
			}
			if(dist[t] == inf) {
				assert(0);
				return -1;
			}
			for(int v = 0; v < n; v++) {
				h[v] += dist[v];
			}
			// s-t ????????????????????£??????????????????
			int d = f;
			for(int v = t; v != s; v = prevv[v]) {
				d = min(d, g[prevv[v]][preve[v]].cap);
			}
			f -= d;
			res += d * h[t];
			for(int v = t; v != s; v = prevv[v]) {
				Edge &e = g[prevv[v]][preve[v]];
				e.cap -= d;
				g[v][e.revEdge].cap += d;
			}
		}
		return res;
	}
	// ??????????????????=???????????????-?????¨??????????????¨???
	void view() {
		for(int i = 0; i < g.size(); i++) {
			for(int j = 0; j < g[i].size(); j++) {
				if(!g[i][j].isRev) {
					Edge& e = g[i][j];
					printf("%3d->%3d (flow:%d)\n", i, e.dst, e.cap_orig - e.cap);
				}
			}
		}
	}
};

struct point {
	double x, y, z;
};

double dist(point p1, point p2) {
	p1.x -= p2.x;
	p1.y -= p2.y;
	p1.z -= p2.z;
	return sqrt(p1.x * p1.x + p1.y * p1.y + p1.z * p1.z);
}

const double INF2 = 10000;

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

	int N, K;
	while(cin >> N >> K, N | K) {
		vector<point> ps(N);

		map<int, int> m;
		for(int i = 0; i < N; i++) {
			cin >> ps[i].x >> ps[i].y >> ps[i].z;
			m[ps[i].z]++;
		}

		if(N <= K) {
			printf("0\n");
			continue;
		}

		bool flag = false;
		for(auto& p : m) {
			if(p.second > K) {
				printf("-1\n");
				flag = true;
				break;
			}
		}
		if(flag) continue;

		vector<int> in(N), out(N);
		for(int i = 0; i < N; i++) {
			in[i] = 2 * i;
			out[i] = in[i] + 1;
		}

		PrimalDual pd(2 * N + 2);
		int S = 2 * N, T = S + 1;

		for(int i = 0; i < N; i++) {
			for(int j = 0; j < N; j++) {
				if(ps[i].z <= ps[j].z) continue;
				pd.add_edge(out[i], in[j], 1, dist(ps[i], ps[j]));
			}
			pd.add_edge(in[i], out[i], 1, -INF2);
			pd.add_edge(out[i], T, 1, 0);
			pd.add_edge(S, in[i], 1, 0);
		}
		pd.add_edge(S, T, 100000, 0);

		double res = pd.solve(S, T, K);
		//pd.view();
		printf("%.10f\n", res + N  * INF2);
	}
}
accuracy: 1
time_ms: 80
memory_kb: 3664
final_rank: 4

code_snippet: #include<bits/stdc++.h>
 
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b))<EPS)
 
using namespace std;

bool LT(double a,double b) { return !equals(a,b) && a < b; }
bool LTE(double a,double b) { return equals(a,b) || a < b; }
 
struct Point {
  double x,y,z;
  Point operator - ( const Point &p ) const { return (Point){x-p.x,y-p.y,z-p.z}; }
  bool operator < ( const Point &p ) const {
    return ( ( !equals(z,p.z) ) ? z > p.z : ( ( !equals(y,p.y) ) ? y < p.y : LT(x,p.x) ) );
  }
};

typedef pair<double,int> ii;

struct Edge{
  int to,cap; double cost; int rev;
  Edge(int to=0,int cap=0,double cost=0,int rev=0):to(to),cap(cap),cost(cost),rev(rev){}
};

const int MAX_V = 1100, IINF = INT_MAX;
int V;
vector<Edge> G[MAX_V];
double h[MAX_V],dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];

inline void add_edge(int from,int to,int cap,double cost){
  G[from].push_back(Edge(to,cap,cost,G[to].size()));
  G[to].push_back(Edge(from,0,-cost,G[from].size()-1));
}

double min_cost_flow(int s,int t){
  double res = 0;
  fill(h,h+V,0);
  while(1){
    priority_queue<ii,vector<ii>,greater<ii> > Q;
    fill(dist,dist+V,IINF);
    dist[s] = 0;
    Q.push(ii(0,s));
    while(!Q.empty()){
      ii p = Q.top(); Q.pop();
      int v = p.second;
      if( dist[v] < p.first ) continue;
      for(int i=0;i<G[v].size();i++){
        Edge &e = G[v][i];
        if( LT(0,e.cap) && !equals(dist[v]+e.cost+h[v]-h[e.to],dist[e.to]) && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to] ) { 
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          Q.push(ii(dist[e.to],e.to));
        }
      }
    }
    //if( dist[t] == IINF ) break;
    rep(v,V) h[v] += dist[v];
    if( h[t] >= 0LL ) break;
    int d = IINF;
    for(int v=t;v!=s;v=prevv[v]) d = min(d,G[prevv[v]][preve[v]].cap);
    res += d * h[t];
    for(int v=t;v!=s;v=prevv[v]){
      Edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}


int N,K;
Point ps[100];

const double MAX = 10000;

double getDist(Point p){ return sqrt(p.x*p.x+p.y*p.y+p.z*p.z); }

void compute(){
  if( N <= K ) { puts("0"); return; }
  map<int,int> counter;
  bool failed = false;
  rep(i,N) counter[(int)ps[i].z]++;
  for(map<int,int>::iterator it = counter.begin(); it != counter.end(); it++ ) {
    if( it->second > K ) { failed = true; break; }
  }
  if( failed ) { puts("-1"); return; }
  rep(i,N*4) G[i].clear();
  int source = N * 2;
  int sink = source + 2;
  V = sink +1;
  add_edge(source,source+1,K,0);
  rep(i,N) { 
    add_edge(source+1,i,1,0);
    add_edge(i,N+i,1,-MAX);
    add_edge(N+i,sink,1,0); 
  }

  rep(i,N) rep(j,N) if( i != j && ps[i].z > ps[j].z ){
    add_edge(N+i,j,1,getDist(ps[i]-ps[j]));
  }

  printf("%.10f\n",min_cost_flow(source,sink)+N*MAX);
}

int main(){
  while( cin >> N >> K, N|K ){
    rep(i,N) cin >> ps[i].x >> ps[i].y >> ps[i].z;
    compute();
  }
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3836
final_rank: 9

code_snippet: #include<bits/stdc++.h>
 
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b))<EPS)
 
using namespace std;

bool LT(double a,double b) { return !equals(a,b) && a < b; }
bool LTE(double a,double b) { return equals(a,b) || a < b; }
 
struct Point {
  double x,y,z;
  Point operator - ( const Point &p ) const { return (Point){x-p.x,y-p.y,z-p.z}; }
  bool operator < ( const Point &p ) const {
    return ( ( !equals(z,p.z) ) ? z > p.z : ( ( !equals(y,p.y) ) ? y < p.y : LT(x,p.x) ) );
  }
};

typedef pair<double,int> ii;

struct Edge{
  int to,cap; double cost; int rev;
  Edge(int to=0,int cap=0,double cost=0,int rev=0):to(to),cap(cap),cost(cost),rev(rev){}
};

const int MAX_V = 1100, IINF = INT_MAX;
int V;
vector<Edge> G[MAX_V];
double h[MAX_V],dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];

inline void add_edge(int from,int to,int cap,double cost){
  G[from].push_back(Edge(to,cap,cost,G[to].size()));
  G[to].push_back(Edge(from,0,-cost,G[from].size()-1));
}

double min_cost_flow(int s,int t){
  double res = 0;
  fill(h,h+V,0);
  while(1){
    priority_queue<ii,vector<ii>,greater<ii> > Q;
    fill(dist,dist+V,IINF);
    dist[s] = 0;
    Q.push(ii(0,s));
    while(!Q.empty()){
      ii p = Q.top(); Q.pop();
      int v = p.second;
      if( dist[v] < p.first ) continue;
      for(int i=0;i<G[v].size();i++){
        Edge &e = G[v][i];
        if( LT(0,e.cap) && !equals(dist[v]+e.cost+h[v]-h[e.to],dist[e.to]) && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to] ) { 
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          Q.push(ii(dist[e.to],e.to));
        }
      }
    }
    //if( dist[t] == IINF ) break;
    rep(v,V) h[v] += dist[v];
    if( h[t] >= 0LL ) break;
    int d = IINF;
    for(int v=t;v!=s;v=prevv[v]) d = min(d,G[prevv[v]][preve[v]].cap);
    res += d * h[t];
    for(int v=t;v!=s;v=prevv[v]){
      Edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}


int N,K;
Point ps[100];

const double MAX = 10000;

double getDist(Point p){ return sqrt(p.x*p.x+p.y*p.y+p.z*p.z); }

void compute(){
  if( N <= K ) { puts("0"); return; }
  map<int,int> counter;
  bool failed = false;
  rep(i,N) counter[(int)ps[i].z]++;
  for(map<int,int>::iterator it = counter.begin(); it != counter.end(); it++ ) {
    if( it->second > K ) { failed = true; break; }
  }
  if( failed ) { puts("-1"); return; }
  rep(i,N*4) G[i].clear();
  int source = N * 2;
  int sink = source + 2;
  V = sink +1;
  add_edge(source,source+1,K,0);
  rep(i,N) { 
    add_edge(source+1,i,1,0);
    add_edge(i,N+i,1,-MAX);
    add_edge(N+i,sink,1,0); 
  }

  rep(i,N) rep(j,N) if( i != j && ps[i].z > ps[j].z ){
    add_edge(N+i,j,1,getDist(ps[i]-ps[j]));
  }

  printf("%.10f\n",min_cost_flow(source,sink)+N*MAX);
}

int main(){
  while( cin >> N >> K, N|K ){
    rep(i,N) cin >> ps[i].x >> ps[i].y >> ps[i].z;
    compute();
  }
  return 0;
}


/* 
const int MAX_V = 110;////////////////////////////////////////////////////////
const float DINF = 1e10;
int N,K;
Point ps[MAX_V];
//double memo[MAX_V][MAX_V][MAX_V][MAX_V];
typedef unsigned long long ull;
const ull base = 1000000007ULL;
unordered_map<ull,float> memo;
float mini;
 
float abs(Point p) { return sqrt(p.x*p.x+p.y*p.y+p.z*p.z); }
 
float rec(int cur,int *prev,int kept){
  if( cur >= N ) return 0;
  //rep(i,4) cout << prev[i] << " "; cout << endl;
  int st[4];
  rep(i,4) st[i] = prev[i];
  sort(st,st+4);
  ull key = 0ULL;
  rep(i,4) {
    key *= base;
    key += (ull)(st[i]+1);
  }
  if( memo.count(key) ) return memo[key];
  //double &ret = memo[st[0]+1][st[1]+1][st[2]+1][st[3]+1];
  //if( !equals(ret,DINF) ) return ret;
  float ret = DINF;
  rep(i,4){
    if( i && prev[i-1] == -1 ) continue;
    int temp = prev[i];
    if( prev[i] == -1 ) {
      if( kept + 1 > K ) continue;
      if( i && prev[i-1] > cur ) continue;
      prev[i] = cur;
      ret = min(ret,rec(cur+1,prev,kept+1));
    } else {
      if( LT(ps[cur].z,ps[prev[i]].z) ) {
        if( i && prev[i-1] > cur ) continue;
        prev[i] = cur;
        ret = min(ret,rec(cur+1,prev,kept)+abs(ps[cur]-ps[temp]));
      }
    }
    prev[i] = temp;
  }
  return memo[key] = ret;
}
 
int main(){
  while( cin >> N >> K, N|K ){
    map<int,int> counter;
    bool failed = false;
    rep(i,N) {
      cin >> ps[i].x >> ps[i].y >> ps[i].z;
      int cnt = ++counter[ps[i].z];
      if( cnt > K ) failed = true;
    }
    if( failed ) { puts("-1"); continue; }
    sort(ps,ps+N);
    //rep(i,N+2) rep(j,N+2) rep(k,N+2) rep(l,N+2) memo[i][j][k][l] = DINF;
    memo.clear();
    int temp[4] = {-1,-1,-1,-1};
    mini = rec(0,temp,0);
    if( equals(mini,DINF) ) puts("-1");
    else printf("%.10lf\n",mini);
  }
  return 0;
}
*/
accuracy: 1
time_ms: 110
memory_kb: 1992
final_rank: 2

code_snippet: #include<bits/stdc++.h>
 
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b))<EPS)
 
using namespace std;

bool LT(double a,double b) { return !equals(a,b) && a < b; }
bool LTE(double a,double b) { return equals(a,b) || a < b; }
 
struct Point {
  double x,y,z;
  Point operator - ( const Point &p ) const { return (Point){x-p.x,y-p.y,z-p.z}; }
  bool operator < ( const Point &p ) const {
    return ( ( !equals(z,p.z) ) ? z > p.z : ( ( !equals(y,p.y) ) ? y < p.y : LT(x,p.x) ) );
  }
};

typedef pair<double,int> ii;

struct Edge{
  int to,cap; double cost; int rev;
  Edge(int to=0,int cap=0,double cost=0,int rev=0):to(to),cap(cap),cost(cost),rev(rev){}
};

const int MAX_V = 1100, IINF = INT_MAX;
int V;
vector<Edge> G[MAX_V];
double h[MAX_V],dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];

inline void add_edge(int from,int to,int cap,double cost){
  G[from].push_back(Edge(to,cap,cost,G[to].size()));
  G[to].push_back(Edge(from,0,-cost,G[from].size()-1));
}

double min_cost_flow(int s,int t){
  double res = 0;
  while(1){
    fill(dist,dist+V,IINF);
    dist[s] = 0;
    bool update = true;
    while( update ){
      update = false;
      rep(v,V){
        if( dist[v] == IINF ) continue;
        rep(i,(int)G[v].size()){
          Edge &e = G[v][i];
          if( e.cap > 0 && !equals(dist[e.to],dist[v]+e.cost) && dist[e.to] > dist[v] + e.cost ){
            //cout << "update dist[" << e.to << "] = dist[" << v << "] + " << e.cost << endl;
            dist[e.to] = dist[v] + e.cost;
            //cout << dist[e.to] << " = " << dist[v] << " + " << e.cost << endl << endl;
            prevv[e.to] = v;
            preve[e.to] = i;
            update = true;
          }
        }
      }
    }

    if( equals(dist[t],IINF) ) break;

    int d = IINF;
    for(int v=t;v!=s;v=prevv[v]) {
      d = min(d,G[prevv[v]][preve[v]].cap);
    }
    if( d == 0 ) break;
    res += d * dist[t];
    for(int v=t;v!=s;v=prevv[v]){
      Edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}

int N,K;
Point ps[100];

const double MAX = 10000;

double getDist(Point p){ return sqrt(p.x*p.x+p.y*p.y+p.z*p.z); }

void compute(){
  map<int,int> counter;
  bool failed = false;
  rep(i,N) counter[(int)ps[i].z]++;
  for(map<int,int>::iterator it = counter.begin(); it != counter.end(); it++ ) {
    if( it->second > K ) { failed = true; break; }
  }
  if( failed ) { puts("-1"); return; }
  rep(i,N*4) G[i].clear();
  int source = N * 2;
  int sink = source + 2;
  V = sink +1;
  add_edge(source,source+1,K,0);
  rep(i,N) { 
    add_edge(source+1,i,1,0);
    add_edge(i,N+i,1,-MAX);
    add_edge(N+i,sink,1,0); 
  }

  rep(i,N) rep(j,N) if( i != j && ps[i].z > ps[j].z ){
    add_edge(N+i,j,1,getDist(ps[i]-ps[j]));
  }

  printf("%.10f\n",min_cost_flow(source,sink)+N*MAX);
}

int main(){
  while( cin >> N >> K, N|K ){
    rep(i,N) cin >> ps[i].x >> ps[i].y >> ps[i].z;
    compute();
  }
  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 1952
final_rank: 1

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

using namespace std;

const int N = 100 + 10;
const int V = 200 + 10;
const int M = V * V * 2;
const long double INF = 1e5;

struct Edge
{
	long double w;
	int c, t;
	Edge *n, *r;
} edges[M], *totEdge, *firstEdge[V];

int n, m;
int x[N], y[N], z[N];

Edge* makeEdge(int s, int t, int c, long double w)
{
	Edge *e = totEdge ++;
	e->t = t; e->n = firstEdge[s]; firstEdge[s] = e;
	e->w = w; e->c = c;
	return e;
}

void addEdge(int s, int t, int c, long double w)
{
	Edge *st = makeEdge(s, t, c, w), *ts = makeEdge(t, s, 0, -w);
	st->r = ts; ts->r = st;
}

long double sqr(long double x)
{
	return x * x;
}

long double dis(int u, int v)
{
	return sqrt(sqr(x[u] - x[v]) + sqr(y[u] - y[v]) + sqr(z[u] - z[v]));
}

int spfa(int s, int t, int tot, long double &ret)
{
	static int in[V];
	static int aug[V];
	static long double dis[V];
	static Edge *prev[V];

	for(int i = 0; i < tot; ++ i) {
		in[i] = false;
		dis[i] = INF * INF;
	}

	queue<int> que;
	que.push(s);
	in[s] = true;
	dis[s] = 0;
	aug[s] = tot;
	aug[t] = 0;

	for( ; que.size(); ) {
		int u = que.front(); que.pop();
		for(Edge *e = firstEdge[u]; e; e = e->n) {
			if (e->c == 0) continue;
			int v = e->t;
			if (dis[v] > dis[u] + e->w) {
				dis[v] = dis[u] + e->w;
				aug[v] = min(aug[u], e->c);
				prev[v] = e;
				if (! in[v]) {
					in[v] = true;
					que.push(v);
				}
			}
		}
		in[u] = false;
	}

	if (aug[t] == 0)
		return false;
	ret += dis[t] * aug[t];
	int by = aug[t];

	for(int u = t; u != s; ) {
		prev[u]->c -= by;
		prev[u]->r->c += by;
		u = prev[u]->r->t;
	}
	return true;
}

long double costFlow(int s, int t, int tot)
{
	long double ret = 0;
	for( ; spfa(s, t, tot, ret); );
	return ret;
}

void solve()
{
	totEdge = edges;
	for(int i = 0; i < n; ++ i) {
		cin >> x[i] >> y[i] >> z[i];
	}
	int s = n + n;
	int t = s + 2;
	for(int i = 0; i <= t; ++ i) {
		firstEdge[i] = 0;
	}
	addEdge(s, s + 1, m, 0);
	for(int i = 0; i < n; ++ i) {
		addEdge(s + 1, i, 1, 0);
		addEdge(i, i + n, 1, -INF);
		addEdge(i + n, t, 1, 0);
		for(int j = 0; j < n; ++ j) {
			if (z[j] < z[i]) {
				addEdge(i + n, j, 1, dis(i, j));
			}
		}
	}

	long double ret = costFlow(s, t, n + n + 3) + n * INF;
	if (ret >= INF) {
		cout << -1 << endl;
	} else {
		printf("%.16f\n", (double)ret);
	}
}

int main()
{
	for( ; cin >> n >> m && (n || m); ) {
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 1788
final_rank: 3

code_snippet: #include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define pb push_back

const int N=300;
const int inf = (1<<20);
/*
struct Edge{int to,cap;double cost;int rev;};

vector<Edge> G[N];
double dist[N];
int prevv[N],preve[N];

void add_edge(int from,int to,int cap,double cost){
  G[from].pb((Edge){to,cap,cost+0,G[to].size()});
  G[to].pb((Edge){from,0,-cost+0,G[from].size()-1});
}

// flow of volume F, s to t
// if it's not posible return -1
double min_cost_flow(int n,int s,int t,int f){
  double res=0;
  while(f>0){
    fill(dist,dist+n,inf);
    dist[s]=0;
    bool update=true;
    //while(update){
    rep(k,n){
      if (!update)break;
      update=false;
      rep(i,n){
	//cout << i <<":: " << dist[i] << endl;
	if (dist[i] == inf)continue;
	rep(j,G[i].size()){
	  Edge &e=G[i][j];
	  //cout << i <<" " << e.to <<" " << dist[e.to]<<
	  //" " << dist[i]+e.cost << endl;
	  if(e.cap > 0 && dist[e.to]>(dist[i] + e.cost)){
	    //printf("%.20lf %.20lf\n",
	    //dist[e.to]-(dist[i]+e.cost),-1);
	    dist[e.to]=dist[i]+e.cost;
	    //cout << i <<" " <<dist[i]<<" " << dist[i]+e.cost<<
	    //" " << dist[e.to] << endl;
	    
	    prevv[e.to]=i;
	    preve[e.to]=j;
	    update=true;
	  }
	}
      }
      //rep(i,n)cout << dist[i]<<" ";cout << endl;
    }
    
    
    if (dist[t] == inf)return -1;

    int d=f;
    for(int v=t;v != s;v = prevv[v]){
      d=min(d,G[prevv[v]][preve[v]].cap);
    }
    f-=d;
    res+=d*dist[t];
    for(int v=t;v != s;v = prevv[v]){
      Edge &e=G[prevv[v]][preve[v]];
      e.cap-=d;
      G[v][e.rev].cap+=d;
    }
  }
  return res;
}
*/

typedef pair<double,int> P;

struct Edge{int to,cap;double cost;int rev;};
vector<Edge> G[N];
double h[N];
double dist[N];
int prevv[N],preve[N];

void add_edge(int from,int to,int cap,double cost){
  G[from].pb((Edge){to,cap,cost+0,G[to].size()});
  G[to].pb((Edge){from,0,-cost+0,G[from].size()-1});
}

// flow of volume F, s to t
// if it's not posible return -1
double min_cost_flow(int n,int s,int t,int f){
  double res=0;
  fill(h,h+n,0);
  while(f>0){
    priority_queue<P,vector<P>,greater<P> >que;
    fill(dist,dist+n,inf);
    dist[s]=0;
    que.push(P(0,s));
    while(!que.empty()){
      P p=que.top();que.pop();
      //cout << p.first <<" " << p.second << endl;
      int v=p.second;
      if (dist[v] < p.first)continue;
      rep(i,G[v].size()){
	Edge &e=G[v][i];
	if (e.cap > 0 && dist[e.to] > dist[v]+e.cost+h[v]-h[e.to]){
	  dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
	  prevv[e.to]=v;
	  preve[e.to]=i;
	  que.push(P(dist[e.to],e.to));
	}
      }
    }

    
    if (dist[t] == inf)return -1;

    for(int v=0;v<n;v++)h[v]+=dist[v];

    int d=f;
    for(int v=t;v != s;v = prevv[v]){
      //cout <<"test " << v << endl;
      //      cout <<"test " << v <<" <- " << prevv[v]<<endl;
      d=min(d,G[prevv[v]][preve[v]].cap);
    }
    f-=d;
    //cout <<"flow " << f << " " << d*dist[t] << endl;
    res+=d*h[t];
    for(int v=t;v != s;v = prevv[v]){
      Edge &e=G[prevv[v]][preve[v]];
      e.cap-=d;
      G[v][e.rev].cap+=d;
    }
  }
  return res;
}


double calc(double x,double y,double z){
  return sqrt(x*x+y*y+z*z);
}

#define IN(i)  (i*2)
#define OUT(i) (i*2+1)

void solve(int n,int k,double *x,double *y,double *z){
  bool cansolve=true;
  rep(i,n){
    int cnt=0;
    rep(j,n){
      if (z[i]==z[j])cnt++;

    }
    if (cnt > k)cansolve=false;
  }
  if (!cansolve){
    printf("-1\n");
    return;
  }    

  if (n <= k){
    printf("0\n");
    return;
  }

  double ans = 1e100;
  REP(t,1,k+1){
    rep(i,2*n+2)G[i].clear();
    rep(i,n){
      rep(j,n){
	if (z[i] > z[j])
	  add_edge(IN(i),OUT(j),1,calc(x[i]-x[j],y[i]-y[j],z[i]-z[j]));
      }
      add_edge(2*n,IN(i),1,0);
      add_edge(OUT(i),2*n+1,1,0);
    }

     rep(i,n*2+2){
       //cout <<i<<":" <<  G[i].size() << endl;
       rep(j,G[i].size()){
	 //cout << i <<" " << G[i][j].to <<" " << G[i][j].cap <<
	 //"/" << G[i][j].cost << endl;
       }
     }
    
    double tmp = min_cost_flow(2*n+2,2*n,2*n+1,n-t);
    //cout << t <<" " << tmp << endl;
    if (tmp == -1)continue;
    ans=min(ans,tmp);
  }  
  //cout <<"ans " << ans << endl;
  printf("%.16lf\n",ans);
}

main(){
  int n,k;
  double x[N],y[N],z[N];
  while(cin>>n>>k && n){
    int m=2*n+2;
    rep(i,2*n+2)G[i].clear();
    rep(i,n)cin>>x[i]>>y[i]>>z[i];
    solve(n,k,x,y,z);
  }
  return false;
}
accuracy: 1
time_ms: 710
memory_kb: 1560
final_rank: 14