Problem:
KND Factory
Problem
KND君は会津大学に在籍する学生プログラマである。彼の住む町の周辺には
N
個の町がある。彼は生クリームが大好きなので毎日生クリームを食べるためにある町に工場を建設した。その工場では毎日
F
リットルの生クリームが製造される。生クリームは運ぶたびに、移動元の町の気温と移動先の町の気温の絶対差だけ傷んでしまう。困ったことにこの近辺の町の気温は寒暖計によって計測できない。しかしながら調査によって、それぞれの町の気温を変数とした
N
個の一次方程式からなる
N
元一次連立方程式を導くことができた。あなたはこれを解くことによって各町の気温を知ることができる。また、ある町から他の町へ生クリームを運搬するにはパイプラインを用いる。パイプラインは一日に送ることのできる生クリームの量が限られている。一日に
F
リットルの生クリームを工場がある町
s
からKND君が住む町
t
へ生クリームをなるべく良い状態で送りたい。町には0から始まる番号がつけられているものとする。方程式の各項は高々ひとつの変数からなり定数項がひとつある。
F
リットルの生クリームはどのような運び方をしても一日以内で任意の町へ送られる。
Input
入力は複数のテストケースからなる。ひとつのテストケースは以下の形式で与えられる。テストケースの数は入力として与えられる。
T
N
s
t
F
a
1,1
a
1,2
...
a
1,N
c
1
a
2,1
a
2,2
...
a
2,N
c
2
...
a
N,1
a
N,2
...
a
N,N
c
N
M
1
d
1,1
d
1,2
...
d
1,M
1
f
1,1
f
1,2
...
f
1,M
1
M
2
d
2,1
d
2,2
...
d
2,M
2
f
2,1
f
2,2
...
f
2,M
2
...
M
N
d
N,1
d
N,2
...
d
N,M
2
f
N,1
f
N,2
...
f
N,M
2
ここで、
T
:テストケースの数
N
:町の数
s
:工場のある町
t
:KND君の住む町
F
:一日に作られる生クリームの量
a
i,j
:連立方程式の未知数としてのi番目の方程式中でj番目の町の気温にかかる係数。もし
a
i,j
=0ならj番目の町の気温はこの方程式に現れないことになる。以下の例も参照してほしい。
c
i
:i番目の方程式の定数項
M
i
:i番目の町が持っている生クリームを移動させる機械の数
d
i,j
:i番目の町が持っているj番目の機械が生クリームを移動させる先の町
f
i,j
:i番目の町が持っているj番目の機械が生クリームを1日に移動させられるリットル量
である。
N
元一次連立方程式を表す行列の入力例:
a +  b      = 6       1  1 0  6
3a + 2b + c  = 10  =>  3  2 1 10
 a - 2b + 3c = 6       1 -2 3  6
a,b,cが町0,1,2の気温を表す。
Constraints
入力は以下の条件を満たす。
入力はすべて整数。
0 <
T
≤ 40
2 <
N
≤ 100
0 ≤
s
<
N
0 ≤
t
<
N
s
≠
t
0 <
F
≤ 1000
0 ≤
M
i
≤
N
-1000 ≤
a
i,j
≤ 1000
0 ≤
f
i,j
< 1000
それぞれの町の気温は一意に定まる。
Output
各テストケースにつき、一日に
F
リットルの生クリームを工場がある町
s
からKND君が住む町
t
に運んだとき、生クリームの傷みの和を最小化した値を一行で出力せよ。この値はジャッジ出力の値と10
-5
より大きい差を持ってはならない。また、町
s
から町
t
へ
F
リットルの生クリームを一日に運べない場合はimpossibleを一行で出力せよ。
Sample Input
3
3 0 2 5
1 1 1 6
3 2 1 10
1 -2 3 6
2
1 2
3 3
1
2
3
0
3 0 2 5
1 1 1 6
3 2 1 10
1 -2 3 6
2
1 2
2 2
1
2
2
0
10 2 7 20
8 9 -5 6 -9 5 1 0 4 9 4
3 -1 -8 0 -5 4 3 0 -3 2 4
-4 5 8 -4 1 -8 -6 3 3 5 -7
-7 0 2 5 8 -5 -9 -8 1 -2 -1
3 8 1 -3 8 2 -5 8 -3 4 -4
-2 5 0 -2 -4 4 -3 9 6 -1 -2
4 1 2 -9 3 5 6 -4 4 -1 -4
-4 6 6 9 -2 1 -9 -3 -7 3 -4
1 -1 6 3 1 -5 9 5 -5 -9 -5
-7 4 6 8 8 4 -4 4 -7 -8 -5
5
1 5 0 6 3
15 17 14 7 15
3
1 5 7
6 8 14
10
3 5 3 5 9 5 9 5 1 4
12 6 16 11 16 7 9 3 13 13
10
9 1 5 6 2 5 8 5 9 4
15 8 8 14 13 13 18 1 12 11
5
3 5 0 4 6
14 15 4 14 11
9
5 0 6 2 7 8 8 6 6
6 5 7 17 17 17 17 19 3
9
7 7 2 7 8 4 7 7 0
4 13 16 10 19 17 19 12 19
3
1 5 1
3 7 16
8
5 7 4 9 1 4 6 8
4 3 6 12 6 19 10 1
4
1 3 6 3
5 15 18 14
Sample Output
10.0000000000
impossible
11.9354380207

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <iomanip>
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 };
    }
};

void inv(int n, vii<double>& a) {
    rep(k, n) {
        double mx = a[k][k];  
        int idx = k;
        for(int i = k + 1; i < n; i++) if (abs(a[i][k]) > mx) {
            idx = i;
            mx = abs(a[i][k]);
        }
        swap(a[k], a[idx]);

        for(int j = n; j >= k; j--) a[k][j] /= a[k][k];

        rep(i, n) {
            if (i == k) continue;
            for (int j = n; j >= k; j--) {
                a[i][j] -= a[i][k] * a[k][j];
            }
        }
    }

}

void solve() {
    int n, s, t, F;
    cin >> n >> s >> t >> F;
    vii<double> a(n, vi<double>(n + 1));
    rep(i, n) rep(j, n + 1) cin >> a[i][j];

    vii<double> b = a;
    inv(n, a);

    MCF mcf(n + 2);
    int S = n, T = n + 1;
    mcf.addedge(S, s, F, 0);
    mcf.addedge(t, T, F, 0);    

    ll mul = 1e10;
    auto diftemp = [&](int i, int j) { return (ll)(abs(a[i][n] - a[j][n]) * mul); };

    rep(i, n) {
        int m;
        cin >> m;
        vi<int> d(m), f(m);
        rep(j, m) cin >> d[j];
        rep(j, m) cin >> f[j];
        rep(j, m) mcf.addedge(i, d[j], f[j], diftemp(i, d[j]));
    }
    double ans = mcf.mincostflow(S, T, F);
    if (ans == -1) cout << "impossible" << endl;
    else cout << fixed << setprecision(12) << (double)ans / mul << endl;
}

int main()
{
    int t;
    cin >> t;    
    while (t--) solve();
    return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 4188
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <iomanip>
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 double inf = 1e18;
    vector<double> dist;       //最短距離(費用)
    vector<int> pv, pe;     //直前の頂点、辺    

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

    struct pii {
        double d; int v; //最短距離(費用)、頂点番号
        pii(double 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<double> 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, double 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
    double mincostflow(int s, int t, long long f) {
        double res = 0;
        double eps = 1e-8;
        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 + eps) 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;
    }
};

void inv(int n, vii<double>& a) {
    rep(k, n) {
        double mx = a[k][k];  
        int idx = k;
        for(int i = k + 1; i < n; i++) if (abs(a[i][k]) > mx) {
            idx = i;
            mx = abs(a[i][k]);
        }
        swap(a[k], a[idx]);

        for(int j = n; j >= k; j--) a[k][j] /= a[k][k];

        rep(i, n) {
            if (i == k) continue;
            for (int j = n; j >= k; j--) {
                a[i][j] -= a[i][k] * a[k][j];
            }
        }
    }

}

void solve() {
    int n, s, t, F;
    cin >> n >> s >> t >> F;
    vii<double> a(n, vi<double>(n + 1));
    rep(i, n) rep(j, n + 1) cin >> a[i][j];

    vii<double> b = a;
    inv(n, a);
    //{
    //    cout << fixed << setprecision(2);
    //    rep(i, n) rep(j, n + 1) cout << a[i][j] << " \n"[j == n];

    //    vi<double> temp(n);
    //    rep(i, n) rep(j, n) temp[i] += b[i][j] * a[j][n];
    //    rep(i, n) cout << temp[i] << " ";
    //    cout << endl;
    //    rep(i, n) cout << fixed << setprecision(10) << a[i][n] << endl;
    //}

    MCF mcf(n + 2);
    int S = n, T = n + 1;
    mcf.addedge(S, s, F, 0);
    mcf.addedge(t, T, F, 0);        

    rep(i, n) {
        int m;
        cin >> m;
        vi<int> d(m), f(m);
        rep(j, m) cin >> d[j];
        rep(j, m) cin >> f[j];
        rep(j, m) mcf.addedge(i, d[j], f[j], abs(a[i][n]-a[d[j]][n]));
    }
    double ans = mcf.mincostflow(S, T, F);
    if (ans == -1) cout << "impossible" << endl;
    else cout << fixed << setprecision(12) << ans << endl;
}

int main()
{
    int t;
    cin >> t;    
    while (t--) solve();
    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 4172
final_rank: 14

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 EPS 0.0000001

typedef vector<double> VEC;
typedef vector<VEC> MATRIX;
typedef pair<double,int> P; //firstは最短距離、secondは頂点の番号

#define NUM 105

//辺を表す構造体{行先、容量、コスト、逆辺のインデックス}
struct Edge{
	Edge(int arg_to,int arg_capacity,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;
	double cost;
};

int V; //頂点数
int H,W;
vector<Edge> G[NUM]; //グラフの隣接リスト表現
double h[NUM]; //ポテンシャル
double dist[NUM]; //最短距離
int pre_node[NUM],pre_edge[NUM]; //直前の頂点と辺
int adj[NUM];


void add_edge(int from,int to,int capacity,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));
}

//流せない場合は-1を返す
double min_cost_flow(int source,int sink,int flow){

	double ret = 0;
	for(int i = 0; i < V; i++)h[i] = 0;
	while(flow > 0){
		//ダイクストラ法を用いてhを更新する
		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]+0.00001 < 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] > 0.00001+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(fabs(dist[sink]-BIG_NUM) < 0.00001){
			//これ以上流せない
			return -1;
		}

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

		//source-sink間最短路に沿って目いっぱい流す
		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;
}



MATRIX gauss_jordan(MATRIX A){

	MATRIX C(H,VEC(W+1));

	for(int row = 0; row < H; row++){
		for(int col = 0; col <= W; col++){
			C[row][col] = A[row][col];
		}
	}

	int base_row;
	double tmp;

	for(int i = 0; i < H; i++){
		base_row = i;
		for(int row = i+1; row < W; row++){
			if(fabs(C[row][i]) > fabs(C[base_row][i])){
				base_row = row;
			}
		}

		if(fabs(C[base_row][i]) < EPS)continue; //操作不要

		if(base_row != i)swap(C[base_row],C[i]);

		tmp = C[i][i]; //係数
		for(int col = 0; col <= W; col++){ //基準行の係数を1にする
			C[i][col] /= tmp;
		}

		for(int row = 0; row < H; row++){
			if(row == i || fabs(C[row][i]) < EPS)continue; //基準行、または該当列が0ならSKIP

			tmp = C[row][i];

			for(int col = i; col <= W; col++){
				C[row][col] -= C[i][col]*tmp;
			}
		}
	}

	return C;
}

void func(){

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

		G[i].clear();
	}

	int source,sink,FLOW;

	scanf("%d %d %d %d",&V,&source,&sink,&FLOW);

	H = V;
	W = V;

	MATRIX A(H,VEC(W+1));

	for(int row = 0; row < H; row++){
		for(int col = 0; col <= W; col++){

			scanf("%lf",&A[row][col]);
		}
	}

	//気温を計算
	A = gauss_jordan(A);

	int num_edge,tmp_capacity;

	for(int loop = 0; loop < V; loop++){

		scanf("%d",&num_edge);
		for(int i = 0; i < num_edge; i++){

			scanf("%d",&adj[i]);
		}

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

			scanf("%d",&tmp_capacity);

			add_edge(loop,adj[i],tmp_capacity,fabs(A[loop][W]-A[adj[i]][W]));
		}
	}

	double ans = min_cost_flow(source,sink,FLOW);

	if(fabs(ans+1.0) < EPS){

		printf("impossible\n");

	}else{

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

int main(){

	int num_case;
	scanf("%d",&num_case);

	for(int loop = 0; loop < num_case; loop++){

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3896
final_rank: 11

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

#define EPS 1e-8
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] > EPS + 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;
	}
};

// ??¬??????????¶???????, Gauss elimination
// O(n^3)
// ???????¶????, forward elimination
// ????????£??\, back substitution

using Num = double;
using Vec = vector<Num>;
using Mat = vector<Vec>;
Vec gaussianElimination(Mat A, Vec b) {
	const int n = A.size(), m = A[0].size();
	int pi = 0, pj = 0;
	while (pi < n && pj < m) {
		for (int i = pi + 1; i < n; i++)
			if (abs(A[i][pj]) > abs(A[pi][pj]))
				A[i].swap(A[pi]), swap(b[i], b[pi]);
		if (abs(A[pi][pj]) > 0) {
			Num d = A[pi][pj];
			for (int j = 0; j < m; j++)
				A[pi][j] /= d;
			b[pi] /= d;
			for (int i = pi + 1; i < n; i++) {
				Num k = A[i][pj];
				for (int j = 0; j < m; j++)
					A[i][j] -= k * A[pi][j];
				b[i] -= k * b[pi];
			}
			pi++;
		}
		pj++;
	}
	for (int i = pi; i < n; i++)
		if (abs(b[i]) > 0)
			return Vec();
	if (pi < m || pj < m)
		return Vec();
	for (int j = m - 1; j >= 0; j--)
		for (int i = 0; i < j; i++)
			b[i] -= b[j] * A[i][j];
	return b;
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int T; cin >> T;
	cout << fixed << setprecision(10);
	while (T--) {
		int N, s, t, F; cin >> N >> s >> t >> F;
		MinimumCostFlow mcf(N);
		Mat a(N, Vec(N));
		Vec c(N);
		rep(i, 0, N) rep(j, 0, N + 1) {
			if (j == N)cin >> c[i];
			else cin >> a[i][j];
		}
		Vec x = gaussianElimination(a, c);
		dump(x);
		rep(i, 0, N) {
			int M; cin >> M;
			vector<int> d(M); rep(j, 0, M) {
				cin >> d[j];
			}
			vector<int> f(M); rep(j, 0, M) {
				cin >> f[j];
			}
			rep(j, 0, M) {
				mcf.addArc(i, d[j], f[j], abs(x[i] - x[d[j]]));
			}
		}
		auto res = mcf.minimumCostFlow(s, t, F);
		if (res == INF)
			cout << "impossible" << endl;
		else
			cout << res << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 4088
final_rank: 15

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

using Array = vector<double>;
using vec = vector<double>;
using Matrix = vector<Array>;
using mat = vector<Array>;
const double eps = 1e-8;

Array GaussJordan(const Matrix& A, const Array& b) {
	int n = A.size();
	Matrix B(n, Array(n + 1));
	for(int i = 0; i < n; i++)
		for(int j = 0; j < n; j++)	B[i][j] = A[i][j];
	for(int i = 0; i < n; i++) B[i][n] = b[i];
	for(int i = 0; i < n; i++) {
		int pivot = i;
		for(int j = i; j < n; j++) {
			if(abs(B[j][i]) > abs(B[pivot][i])) pivot = j;
		}
		swap(B[i], B[pivot]);
		if(abs(B[i][i]) < eps) return Array();
		for(int j = i + 1; j <= n; j++) B[i][j] /= B[i][i];
		for(int j = 0; j < n; j++) {
			if(i != j) {
				for(int k = i + 1; k <= n; k++) B[j][k] -= B[j][i] * B[i][k];
			}
		}
	}

	Array x(n);
	for(int i = 0; i < n; i++) x[i] = B[i][n];
	return x;
}
const int MAX_V = 100010;
typedef int Capacity;
typedef double Cost;
const Cost inf = 1e9;

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;
	vector<int> top;
	PrimalDual(int n_) : n(n_), g(vector<vector<Edge> >(n_)) {}
	void add_edge(int src, int dst, Capacity cap, Cost cost) { // ?????????
		g[src].push_back(Edge{ dst, cap, cost, (int)g[dst].size(), false });
		g[dst].push_back(Edge{ src, 0, -cost, (int)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];

		fill(h, h + n, 0);
		if(top.size()) {
			assert(top.size() == n);
			for(int i = 0; i < n; i++) {
				int v = top[i];
				for(int i = 0; i < g[v].size(); i++) {
					Edge& e = g[v][i];
					if(e.cap == 0) continue;
					int u = e.dst;
					h[u] = min(h[u], h[v] + e.cost);
				}
			}
		}

		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.push(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] + eps) {
						dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
						prevv[e.dst] = v;
						preve[e.dst] = i;
						q.push(pcv(dist[e.dst], e.dst));
					}
				}
			}
			if(abs(dist[t] - inf) < eps) {
				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);
				}
			}
		}
	}
};

int d[1000];
int f[1000];

void solve() {

	int N, S, T, F;
	cin >> N >> S >> T >> F;

	Matrix A(N, Array(N));
	Array b(N);
	for(int i = 0; i < N; i++) {
		for(int j = 0; j < N; j++) {
			cin >> A[i][j];
		}
		cin >> b[i];
	}

	Array tm = GaussJordan(A, b);

	PrimalDual pd(N);
	for(int i = 0; i < N; i++) {
		int M;
		cin >> M;
		for(int j = 0; j < M; j++) {
			cin >> d[j];
		}
		for(int j = 0; j < M; j++) {
			cin >> f[j];
		}
		for(int j = 0; j < M; j++) {
			pd.add_edge(i, d[j], f[j], abs(tm[i] - tm[d[j]]));
		}
	}
	Cost res = pd.solve(S, T, F);
	if(res == -1) {
		cout << "impossible" << endl;
	}
	else {
		cout << fixed << setprecision(15) << res << endl;
	}
}

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

	int T;
	cin >> T;
	while(T--) solve();
}
accuracy: 1
time_ms: 120
memory_kb: 3984
final_rank: 12

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

using Array = vector<double>;
using vec = vector<double>;
using Matrix = vector<Array>;
using mat = vector<Array>;
const double eps = 1e-8;

vec gauss_jordan(const mat&A, const vec&b) {
	int n = A.size();
	mat B(n, vec(n + 1));
	for(int i = 0; i < n; i++)
		for(int j = 0; j < n; j++)B[i][j] = A[i][j];
	for(int i = 0; i < n; i++)B[i][n] = b[i];
	for(int i = 0; i < n; i++) {
		int pivot = i;
		for(int j = i; j<n; j++)
			if(abs(B[j][i])>abs(B[pivot][i]))pivot = j;
		swap(B[i], B[pivot]);
		if(abs(B[i][i]) < 0.0000001)return vec();
		for(int j = i + 1; j <= n; j++)B[i][j] /= B[i][i];
		for(int j = 0; j < n; j++) {
			if(i != j)
				for(int k = i + 1; k <= n; k++)B[j][k] -= B[j][i] * B[i][k];
		}
	}
	vec x(n);
	for(int i = 0; i < n; i++)x[i] = B[i][n];
	return x;
}
const int MAX_V = 100010;
typedef int Capacity;
typedef double Cost;
const Cost inf = 1e9;

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;
	vector<int> top;
	PrimalDual(int n_) : n(n_), g(vector<vector<Edge> >(n_)) {}
	void add_edge(int src, int dst, Capacity cap, Cost cost) { // ?????????
		g[src].push_back(Edge{ dst, cap, cost, (int)g[dst].size(), false });
		g[dst].push_back(Edge{ src, 0, -cost, (int)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];

		fill(h, h + n, 0);
		if(top.size()) {
			assert(top.size() == n);
			for(int i = 0; i < n; i++) {
				int v = top[i];
				for(int i = 0; i < g[v].size(); i++) {
					Edge& e = g[v][i];
					if(e.cap == 0) continue;
					int u = e.dst;
					h[u] = min(h[u], h[v] + e.cost);
				}
			}
		}

		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.push(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] + eps) {
						dist[e.dst] = dist[v] + e.cost + h[v] - h[e.dst];
						prevv[e.dst] = v;
						preve[e.dst] = i;
						q.push(pcv(dist[e.dst], e.dst));
					}
				}
			}
			if(abs(dist[t] - inf) < eps) {
				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);
				}
			}
		}
	}
};

int d[1000];
int f[1000];

void solve() {

	int N, S, T, F;
	cin >> N >> S >> T >> F;

	Matrix A(N, Array(N));
	Array b(N);
	for(int i = 0; i < N; i++) {
		for(int j = 0; j < N; j++) {
			cin >> A[i][j];
		}
		cin >> b[i];
	}

	Array tm = gauss_jordan(A, b);

	PrimalDual pd(N);
	for(int i = 0; i < N; i++) {
		int M;
		cin >> M;
		for(int j = 0; j < M; j++) {
			cin >> d[j];
		}
		for(int j = 0; j < M; j++) {
			cin >> f[j];
		}
		for(int j = 0; j < M; j++) {
			pd.add_edge(i, d[j], f[j], abs(tm[i] - tm[d[j]]));
		}
	}
	Cost res = pd.solve(S, T, F);
	if(res == -1) {
		cout << "impossible" << endl;
	}
	else {
		cout << fixed << setprecision(15) << res << endl;
	}
}

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

	int T;
	cin >> T;
	while(T--) solve();
}
accuracy: 1
time_ms: 120
memory_kb: 4032
final_rank: 13

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

/* verified AOJ1327 One-Dimensional Cellular Automaton
~Matrix~
??????????°????????¨?????????§??????
vector iostream cmath cassert ??????
Matrix a(VV), b(VV);
?????????:a*b
????????????:l*a
???:a+b
???:a-b
??¢???:a.transport()
?????????:a.cofactor()
?????????:a.det()
a???i???j??????:a.get(i,j)???
a???i??????j?????????k?????£??\:set(i,j,k)
????????????a[i][j] (a[i][j]=k)
a???x???:a.pow(x)
n*n?????¬??????E:Matrix(n)
m*n 0??????:Matrix(m,n)
m*n ??¨????´????p?????????:Matrix(m,n,p)
Row???row??§????????????(m*1??????):Matrix(row)
**(??´??°??????)**
????§????:a.triangulate()
?????????:a.rank()
?????????:a.inverse()
//(????????????a.det()?????????a.pre_inverse()??§?±??????? ??´??°???)
??¬??????????¶???????:a.rowReduction()
//??£???????¬?????¨????????§£??????
***
*/

#include <vector>
#include <iostream>
#include <cmath>
#include <cassert>
using namespace std;

typedef double Elem;
typedef vector<Elem> Row;
typedef vector<Row> VV;

typedef long double ld;
const ld EPS = 1e-11;

const bool isZero(const Elem e) {
	return abs(e) < EPS;
}

struct Matrix {
	VV matrix;
	int n, m;

	Matrix(const VV &matrix_);
	explicit Matrix(int n_);
	explicit Matrix(const Row &row);
	Matrix(int m_, int n_);
	Matrix(int m_, int n_, Elem e);

	const Elem get(const int i, const int j) const;
	void set(const int x, const int y, const Elem k);

	const Matrix operator + (const Matrix &rhs) const;
	const Matrix operator * (const Matrix &rhs) const;
	const Matrix operator - (const Matrix &rhs) const;
	Matrix &operator += (const Matrix &rhs);
	Matrix &operator *= (const Matrix &rhs);
	Matrix &operator -= (const Matrix &rhs);

	Row &operator[](const int x);

	const Matrix transport() const;
	const Matrix pow(int x) const;
	const Matrix cofactor(int x, int y) const;
	const Elem det() const;

	const Matrix triangulate() const;
	const int rank() const;

	//?????????????????¨????????°???(?????????)*(?????????)?????????
	//A:matrix,return det A * A^-1
	const Matrix pre_inverse() const;
	const Matrix inverse() const;
	const Matrix rowReduction() const;
};

const Matrix operator * (const Elem lambda, const Matrix &rhs) {
	Matrix tmp(rhs);
	for (int i = 0; i < rhs.m; i++)
		for (int j = 0; j < rhs.n; j++)
			tmp.set(i, j, tmp.get(i, j) * lambda);
	return tmp;
}

Matrix::Matrix(const VV &matrix_) : matrix(matrix_) {
	m = matrix_.size();
	if (m == 0) n = 0;
	else n = matrix_[0].size();
}
Matrix::Matrix(int n_) : m(n_), n(n_) {
	matrix = VV(n, Row(n, 0));
	for (int i = 0; i < n; ++i)
		set(i, i, 1);
}
Matrix::Matrix(const Row &row) : m(1), n(row.size()), matrix(VV(1, row)) {
	//size???m???vector<Elem>??????mx1???????????????
	(*this) = transport();
}
Matrix::Matrix(int m_, int n_) : m(m_), n(n_) {
	matrix = VV(m, Row(n, 0));
}
Matrix::Matrix(int m_, int n_, Elem e) : m(m_), n(n_) {
	matrix = VV(m, Row(n, e));
}

const Elem Matrix::get(const int i, const int j) const {
	if (0 <= i && i < m && 0 <= j && j < n)
		return matrix[i][j];

	cerr << "get(" << i << "," << j << ")is not exist." << endl;
	throw;
}
void Matrix::set(const int i, const int j, const Elem k) {
	if (0 <= i && i < m && 0 <= j && j < n) {
		*(matrix[i].begin() + j) = k;
		return;
	}
	cerr << "set(" << i << "," << j << ")is not exist." << endl;
	throw;
}

const Matrix Matrix::operator + (const Matrix &rhs) const {
	assert(m == rhs.m && n == rhs.n);

	Matrix tmp(m, n, 0);
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			tmp.set(i, j, get(i, j) + rhs.get(i, j));
		}
	}
	return tmp;
}

const Matrix Matrix::operator * (const Matrix &rhs) const {
	assert(n == rhs.m);

	Matrix tmp(m, rhs.n, 0);
	Elem sum;
	for (int i = 0; i < m; i++)
		for (int j = 0; j < rhs.n; j++) {
			sum = 0;
			for (int k = 0; k < n; k++) {
				sum += get(i, k) * rhs.get(k, j);
			}
			tmp.set(i, j, sum);
		}
	return tmp;
}

const Matrix Matrix::operator - (const Matrix &rhs) const {
	return *this + ((Elem)-1 * rhs);
}

Matrix &Matrix::operator += (const Matrix &rhs) {
	return *this = *this + rhs;
}

Matrix &Matrix::operator *= (const Matrix &rhs) {
	return *this = *this * rhs;;
}

Matrix &Matrix::operator -= (const Matrix &rhs) {
	return *this = *this - rhs;
}

Row &Matrix::operator[](const int x) {
	return matrix[x];
}

const Matrix Matrix::transport() const {
	VV tmp;
	for (int i = 0; i < n; i++) {
		Row row;
		for (int j = 0; j < m; j++)
			row.push_back(get(j, i));
		tmp.push_back(row);
	}
	return tmp;
}

const Matrix Matrix::pow(int x) const {
	Matrix tmp(*this), e(m);
	for (int i = 1; i <= x; i <<= 1) {
		if ((x & i) > 0)
			e = e * tmp;
		tmp = tmp * tmp;
	}
	return e;
}

const Matrix Matrix::cofactor(int x, int y) const {
	VV tmp;
	for (int i = 0; i < m; i++) {
		if (x == i) continue;
		Row row;
		for (int j = 0; j < n; j++) {
			if (y == j) continue;
			row.push_back(get(i, j));
		}
		tmp.push_back(row);
	}
	return Matrix(tmp);
}

const Elem Matrix::det() const {
	assert(n == m);
Matrix tri = triangulate();
Elem ans = 1;
for (int i = 0; i < n; ++i) {
	ans *= tri[i][i];
}
return ans;

	if (m == 1)
		return get(0, 0);
	Elem sum = 0;
	for (int i = 0; i < m; i++) {
		sum += ((i % 2 == 0 ? 1 : -1) * get(i, 0)) * Matrix(cofactor(i, 0)).det();
	}
	return sum;
}

const Matrix Matrix::triangulate() const {
	Matrix tmp(*this);
	Elem e;
	int p = 0;
	for (int i = 0; i < m && p < n; i++, p++) {
		if (isZero(tmp.get(i, p))) {
			tmp.set(i, p, 0);
			bool flag = true;
			for (int j = i + 1; j < m; j++)
				if (!isZero(tmp.get(j, p))) {
					for (int k = 0; k < n; k++)
						tmp.set(i, k, tmp.get(i, k) + tmp.get(j, k));
					//tmp[i].swap(tmp[j]);
					flag = false;
					break;
				}
			if (flag) {
				i--;
				continue;
			}
		}
		for (int j = i + 1; j < m; j++) {
			e = tmp.get(j, p) / tmp.get(i, p);
			for (int k = 0; k < n; k++)
				tmp.set(j, k, tmp.get(j, k) - tmp.get(i, k) * e);
		}
	}
	return tmp;
}

const int Matrix::rank() const {
	Matrix tmp(triangulate());
	for (int i = min(tmp.m - 1, tmp.n - 1); i >= 0; i--) {
		for (int j = tmp.n - 1; j >= i; j--)
			if (isZero(tmp.get(i, j)))
				continue;
			else
				return i + 1;
	}
	return 0;
}

const Matrix Matrix::pre_inverse() const {
	assert(m == n);

	Matrix tmp(m, n, 0);
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			tmp.set(i, j, ((i + j) % 2 == 0 ? 1 : -1)*cofactor(i, j).det());
	return tmp.transport();
}

/*O(n!)????£?
const Matrix Matrix::inverse() const {
Matrix tmp(pre_inverse());
Elem e = det();
assert(!isZero(e));
tmp = 1 / e * tmp;
return tmp.transport();
}*/

const Matrix Matrix::inverse() const {
	assert(m == n);

	Matrix tmp(m, n * 2), tmp2(m, n);
	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			tmp.set(i, j, get(i, j));
	for (int i = 0; i < m; i++)
		tmp.set(i, i + n, 1);

	tmp = tmp.rowReduction();

	//?????????????????¨??????????????????????????§??????
	for (int i = 0; i < m; i++)
		assert(isZero(tmp.get(i, i) - 1));

	for (int i = 0; i < m; i++)
		for (int j = 0; j < n; j++)
			tmp2.set(i, j, tmp.get(i, j + n));

	return tmp2;
}

/*
a b c j
d e f k
g h i l

ax+by+cz=j;
dx+ey+fz=k;
gx+hy+iz=l;

|
V

1 0 0 x
0 1 0 y
0 0 1 z
???????????????
*/
const Matrix Matrix::rowReduction() const {
	Matrix tmp(*this);
	Elem e;
	int p = 0;
	for (int i = 0; i < m && p < n; i++, p++) {
		if (isZero(tmp.get(i, p))) {
			tmp.set(i, p, 0);
			bool flag = true;
			for (int j = i + 1; j < m; j++)
				if (!isZero(tmp.get(j, p))) {
					for (int k = 0; k < n; k++)
						tmp.set(i, k, tmp.get(i, k) + tmp.get(j, k));
					//tmp[i].swap(tmp[j]);
					flag = false;
					break;
				}
			if (flag) {
				i--;
				continue;
			}
		}
		e = 1 / tmp.get(i, p);
		tmp.set(i, p, 1);
		for (int k = i + 1; k < n; k++)
			tmp.set(i, k, tmp.get(i, k)*e);
		for (int j = 0; j < m; j++) {
			if (i == j) continue;
			e = tmp.get(j, p);
			for (int k = 0; k < n; k++)
				tmp.set(j, k, tmp.get(j, k) - tmp.get(i, k) * e);
		}
	}
	return tmp;
}

typedef ld  Weight;
struct Edge {
	int src, dest;
	int cap, rev;
	Weight weight;
	bool operator < (const Edge &rhs) const { return weight > rhs.weight; }
};

const int V = 4000;
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
Weight h[V];                //??????????????£???
Weight dist[V];             //???????????¢
int prevv[V], preve[V];  //??´???????????¨??????

void add_edge(Graph &g, int src, int dest, int cap, Weight weight) {
	g[src].push_back(Edge{ src, dest, cap, (int)g[dest].size(), weight });
	g[dest].push_back(Edge{ dest, src, 0, (int)g[src].size() - 1, -weight });
}
#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(auto i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const Weight INF = 2147483647;
const Weight eps = 1e-9;
//????????????double?????????eps?????????
Weight min_cost_flow(Graph &g, int s, int t, int f) {
	Weight res = 0;
	memset(h, 0, sizeof(h));
	typedef pair<Weight, int> P;
	while (f > 0) {
		priority_queue<P, vector<P>, greater<P> > que;
		fill(dist, dist + V, INF);
		dist[s] = 0;
		que.push(P(0, s));
		while (!que.empty()) {
			P p = que.top(); que.pop();
			const 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.dest] > dist[v] + e.weight + h[v] - h[e.dest] + eps) {
					dist[e.dest] = dist[v] + e.weight + h[v] - h[e.dest];
					prevv[e.dest] = v;
					preve[e.dest] = i;
					que.push(P(dist[e.dest], e.dest));
				}
			}
		}
		if (dist[t] == INF) return -1;
		REP(v, V) h[v] = h[v] + dist[v];

		int d = f;
		for (int v = t; v != s; v = prevv[v]) d = min(d, g[prevv[v]][preve[v]].cap);
		f -= d;
		res = 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 main() {
	int T; cin >> T;
	while (T--) {
		int N, S, T, F; cin >> N >> S >> T >> F;
		vector<ld>ts;
		{
			Matrix mat(N, N + 1);
			for (int i = 0; i < N; ++i) {
				for (int j = 0; j < N + 1; ++j) {
					int a; cin >> a;
					mat[i][j] = a;
				}
			}
			mat = mat.rowReduction();
			for (int i = 0; i < N; ++i) {
				ts.push_back(mat[i][N]);
			}
		}
		Graph g(N);
		for (int i = 0; i < N; ++i) {
			int M; cin >> M;
			vector<int>ds, fs;
			for (int j = 0; j < M; ++j) {
				int d; cin >> d; ds.push_back(d);
			}
			for (int j = 0; j < M; ++j) {
				int f; cin >> f; fs.push_back(f);
			}
			for (int j = 0; j < M; ++j) {
				add_edge(g, i, ds[j], fs[j], abs(ts[i] - ts[ds[j]]));
			}
		}
		ld ans = min_cost_flow(g, S, T, F);
		if (ans < 0)cout << "impossible" << endl;
		else
		{

			cout << setprecision(10) << fixed << ans << endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 4096
final_rank: 16

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define MAX_V 300
#define INF 1e9
const double EPS = 1e-8;
typedef vector<double> vec;
typedef vector<vec> mat;
typedef pair<double, int> P;
 
struct edge {
    int to, cap, rev;
    double cost;
    edge(int to, int cap, int rev, double cost) :
	to(to), cap(cap), rev(rev), cost(cost) {}
};
 
int V;
vector<edge> G[MAX_V];
double dist[MAX_V], h[MAX_V];;
int prevv[MAX_V], preve[MAX_V];
 
void add_edge(int from, int to, int cap, double cost){
    G[from].push_back(edge(to, cap, G[to].size(), cost));
    G[to].push_back(edge(from, 0, G[from].size()-1, -cost));
}
 
double min_cost_flow(int s, int t, int f)
{
    double res = 0;
    fill(h, h+V, 0);
    while (f > 0) {
	priority_queue<P, vector<P>, greater<P>> Q;
	fill(dist, dist+V, INF);
	dist[s] = 0;
	Q.push(P(0, s));
	while (!Q.empty()) {
	    P p = Q.top(); Q.pop();
	    int v = p.second;
	    if (dist[v] < p.first) 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 + h[v] - h[e.to] + EPS) {
		    dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
		    prevv[e.to] = v;
		    preve[e.to] = i;
		    Q.push(P(dist[e.to], e.to));
		}
	    }
	}
	if (dist[t] == INF) {
	    return -1;
	}
	for (int v = 0; v < V; v++) {
	    h[v] += dist[v];
	}
	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.rev].cap += d;
	}
    }
    return res;
}
 
vec gauss_jordan(const mat &A, const vec &b)
{
    int n = A.size();
    mat B(n, vec(n+1));
    for (int i = 0; i < n; i++){
	for(int j = 0 ; j < n ; j++) {
	    B[i][j] = A[i][j];
	}
    }
    for (int i = 0; i < n; i++) {
	B[i][n] = b[i];
    }
    for (int i = 0; i < n; i++) {
	int pivot = i;
	for (int j = i ; j < n ; j++) {
	    if (abs(B[j][i]) > abs(B[pivot][i])) {
		pivot = j;
	    }
	}
	swap(B[i],B[pivot]);
	if (abs(B[i][i]) < EPS) return vec();
	for (int j = i+1; j <= n; j++) {
	    B[i][j] /= B[i][i];
	}
	for (int j = 0; j < n; j++) {
	    if (i != j) {
		for (int k = i+1; k <= n; k++) {
		    B[j][k] -= B[j][i]*B[i][k];
		}
	    }
	}
    }
    vec x(n);
    for (int i = 0; i < n; i++) {
	x[i] = B[i][n];
    }
    return x;
}
 
void init()
{
    for (int i = 0; i < MAX_V; i++) {
	G[i].clear();
    }
}
 
int main()
{
    int Tc;
    scanf("%d", &Tc);
    while (Tc--) {
	int N, s, t, F;
	init();
        scanf("%d %d %d %d", &N, &s, &t, &F);
	mat a(N, vec(N)); vec c(N);
	for (int i = 0; i < N; i++) {
	    for (int j = 0; j < N; j++) {
                scanf("%lf", &a[i][j]);
	    }
            scanf("%lf", &c[i]);            
	}
	vec res = gauss_jordan(a, c);
	for (int i = 0; i < N; i++) {
	    int M, d[N], f;
            scanf("%d", &M);
	    for (int j = 0; j < M; j++) {
		scanf("%d", &d[j]);
	    }
	    for (int j = 0; j < M; j++) {
                scanf("%d", &f);
		add_edge(i, d[j], f, abs(res[i]-res[d[j]]));
	    }
	}
	V = N;
	double ans = min_cost_flow(s, t, F);
	if (ans == -1) {
	    printf("impossible\n");
	} else {
	    printf("%.6f\n", ans);
	}
    }
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 3700
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_V 105
#define INF 1000000001
typedef pair< double ,int> P;

struct edge {
  int to;
  int cap;
  int rev;
  double cost;
};

int V;
vector<edge> G[MAX_V];
double h[MAX_V];
double dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];

void init_edge(){
  for(int i=0;i<MAX_V;i++)G[i].clear();
}

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

double min_cost_flow(int s,int t,int f){
  double eps = 1e-5;
  double res = 0;
  fill(h,h+V,0.0);
  
  while(f>0){
    
    priority_queue< P, vector<P>, greater<P> >  que;
    fill( dist, dist+V , (double)INF );
    dist[s]=0;
    que.push(P(0,s));

    // fill ( prevv , prevv + V , s );
    
    while(!que.empty()){
      P p = que.top(); que.pop();
      int v = p.second;
      if(dist[v]+eps < p.first)continue;
      for(int i=0;i<(int)G[v].size();i++){
        edge &e = G[v][i];
        if(e.cap>0&&dist[e.to] > eps+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){
    if( dist[t] > INF - eps ){
      return -1;
    }
    for(int v=0;v<V;v++)h[v]+=dist[v]; 

    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.rev].cap += d;
    }

  }
  return res;
}

typedef vector< double > vec;
typedef vector<vec> mat;


vec gauss_jordan(const mat&A,const vec&b){
  int n=A.size();
  mat B(n,vec(n+1));
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)B[i][j]=A[i][j];
  for(int i=0;i<n;i++)B[i][n]=b[i];
  for(int i=0;i<n;i++){
    int pivot=i;
    for(int j=i;j<n;j++)
      if(abs(B[j][i])>abs(B[pivot][i]))pivot=j;
    swap(B[i],B[pivot]);
    if(abs(B[i][i])< 0.0000001 )return vec();
    for(int j=i+1;j<=n;j++)B[i][j]/=B[i][i];
    for(int j=0;j<n;j++){
      if(i!=j)
        for(int k=i+1;k<=n;k++)B[j][k]-=B[j][i]*B[i][k];
    }
  }
  vec x(n);
  for(int i=0;i<n;i++)x[i]=B[i][n];
  return x;
}

int N,si,ti,F;
int M;

int main(){
  int T;
  cin>>T;
  while(T--){

    init_edge();
    cin>>N>>si>>ti>>F;
    
    mat A( N , vec(N) );
    vec B( N );
    
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++)scanf("%lf",&A[i][j]);
      scanf("%lf",&B[i]);
    }
    
    vec C=gauss_jordan(A,B);
    
    for(int i=0;i<N;i++){
      
      cin>>M;
      vector<int> d(M);
      vector<int> f(M);
      for(int j=0;j<M;j++)scanf("%d",&d[j]);
      for(int j=0;j<M;j++)scanf("%d",&f[j]);
      
      for(int j=0;j<M;j++){
        add_edge(i,d[j],f[j], abs(C[i]-C[d[j]]) );
        
      }
    }
    V=N;
    double ans=min_cost_flow(si,ti,F);
    if(ans<=-1.0){
      cout<<"impossible"<<endl;
    }else{
      printf("%.10f\n",ans);
    }
  }
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 2116
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_V 105
#define INF 1000000001
typedef pair< double ,int> P;

struct edge {
  int to;
  int cap;
  int rev;
  double cost;
};

int V;
vector<edge> G[MAX_V];
double h[MAX_V];
double dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];

void init_edge(){
  for(int i=0;i<MAX_V;i++)G[i].clear();
}

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

double min_cost_flow(int s,int t,int f){
  double eps = 1e-5;
  double res = 0;
  fill(h,h+V,0.0);
  
  while(f>0){
    
    priority_queue< P, vector<P>, greater<P> >  que;
    fill( dist, dist+V , (double)INF );
    dist[s]=0;
    que.push(P(0,s));

    // fill ( prevv , prevv + V , s );
    
    while(!que.empty()){
      P p = que.top(); que.pop();
      int v = p.second;
      if(dist[v]+eps < p.first)continue;
      for(int i=0;i<(int)G[v].size();i++){
        edge &e = G[v][i];
        if(e.cap>0&&dist[e.to] > eps+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<V;v++)h[v]+=dist[v]; 

    int d=f;
    for(int v=t;v!=s;v=prevv[v]){
      d=min(d,G[prevv[v]][preve[v]].cap);
    }
    assert( d > 0 );
    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.rev].cap += d;
    }

  }
  return res;
}

typedef vector< double > vec;
typedef vector<vec> mat;


vec gauss_jordan(const mat&A,const vec&b){
  int n=A.size();
  mat B(n,vec(n+1));
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)B[i][j]=A[i][j];
  for(int i=0;i<n;i++)B[i][n]=b[i];
  for(int i=0;i<n;i++){
    int pivot=i;
    for(int j=i;j<n;j++)
      if(abs(B[j][i])>abs(B[pivot][i]))pivot=j;
    swap(B[i],B[pivot]);
    if(abs(B[i][i])< 0.0000001 )return vec();
    for(int j=i+1;j<=n;j++)B[i][j]/=B[i][i];
    for(int j=0;j<n;j++){
      if(i!=j)
        for(int k=i+1;k<=n;k++)B[j][k]-=B[j][i]*B[i][k];
    }
  }
  vec x(n);
  for(int i=0;i<n;i++)x[i]=B[i][n];
  return x;
}

int N,si,ti,F;
int M;

int main(){
  int T;
  cin>>T;
  while(T--){

    init_edge();
    cin>>N>>si>>ti>>F;
    
    mat A( N , vec(N) );
    vec B( N );
    
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++)scanf("%lf",&A[i][j]);
      scanf("%lf",&B[i]);
    }
    
    vec C=gauss_jordan(A,B);
    
    for(int i=0;i<N;i++){
      
      cin>>M;
      vector<int> d(M);
      vector<int> f(M);
      for(int j=0;j<M;j++)scanf("%d",&d[j]);
      for(int j=0;j<M;j++)scanf("%d",&f[j]);
      
      for(int j=0;j<M;j++){
        add_edge(i,d[j],f[j], abs(C[i]-C[d[j]]) );
        
      }
    }
    V=N;
    double ans=min_cost_flow(si,ti,F);
    if(ans<=-1.0){
      cout<<"impossible"<<endl;
    }else{
      printf("%.10f\n",ans);
    }
  }
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 2116
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MAX_V 105
#define INF 1000000001
typedef pair< double ,int> P;

struct edge {
  int to;
  int cap;
  int rev;
  double cost;
};

int V;
vector<edge> G[MAX_V];
double h[MAX_V];
double dist[MAX_V];
int prevv[MAX_V],preve[MAX_V];

void init_edge(){
  for(int i=0;i<MAX_V;i++)G[i].clear();
}

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

double min_cost_flow(int s,int t,int f){
  double eps = 1e-5;
  double res = 0;
  fill(h,h+V,0.0);
  
  while(f>0){
    
    priority_queue< P, vector<P>, greater<P> >  que;
    fill( dist, dist+V , (double)INF );
    dist[s]=0;
    que.push(P(0,s));

    fill ( prevv , prevv + V , s );
    
    while(!que.empty()){
      P p = que.top(); que.pop();
      int v = p.second;
      if(dist[v]+eps < p.first)continue;
      for(int i=0;i<(int)G[v].size();i++){
        edge &e = G[v][i];
        if(e.cap>0&&dist[e.to] > eps+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<V;v++)h[v]+=dist[v]; 

    int d=f;
    for(int v=t;v!=s;v=prevv[v]){
      d=min(d,G[prevv[v]][preve[v]].cap);
    }
    assert( d > 0 );
    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.rev].cap += d;
    }

  }
  return res;
}

typedef vector< double > vec;
typedef vector<vec> mat;


vec gauss_jordan(const mat&A,const vec&b){
  int n=A.size();
  mat B(n,vec(n+1));
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)B[i][j]=A[i][j];
  for(int i=0;i<n;i++)B[i][n]=b[i];
  for(int i=0;i<n;i++){
    int pivot=i;
    for(int j=i;j<n;j++)
      if(abs(B[j][i])>abs(B[pivot][i]))pivot=j;
    swap(B[i],B[pivot]);
    if(abs(B[i][i])< 0.0000001 )return vec();
    for(int j=i+1;j<=n;j++)B[i][j]/=B[i][i];
    for(int j=0;j<n;j++){
      if(i!=j)
        for(int k=i+1;k<=n;k++)B[j][k]-=B[j][i]*B[i][k];
    }
  }
  vec x(n);
  for(int i=0;i<n;i++)x[i]=B[i][n];
  return x;
}

int N,si,ti,F;
int M;

int main(){
  int T;
  cin>>T;
  while(T--){

    init_edge();
    cin>>N>>si>>ti>>F;
    
    mat A( N , vec(N) );
    vec B( N );
    
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++)scanf("%lf",&A[i][j]);
      scanf("%lf",&B[i]);
    }
    
    vec C=gauss_jordan(A,B);
    
    for(int i=0;i<N;i++){
      
      cin>>M;
      vector<int> d(M);
      vector<int> f(M);
      for(int j=0;j<M;j++)scanf("%d",&d[j]);
      for(int j=0;j<M;j++)scanf("%d",&f[j]);
      
      for(int j=0;j<M;j++){
        add_edge(i,d[j],f[j], abs(C[i]-C[d[j]]) );
        
      }
    }
    V=N;
    double ans=min_cost_flow(si,ti,F);
    if(ans<=-1.0){
      cout<<"impossible"<<endl;
    }else{
      printf("%.10f\n",ans);
    }
  }
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 2116
final_rank: 2

code_snippet: #include<bits/stdc++.h>
#define INF (1e9)
#define N_MAX 100
using namespace std;
const double EPS=1E-8;
typedef vector<double> vec;
typedef vector<vec> mat;

struct edge{
  int to,cap,rev;
  double cost;
};

int V;
vector<edge> G[N_MAX];
double dist[N_MAX];
int prevv[N_MAX],preve[N_MAX];

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

double min_cost_flow(int s,int t,int f){
  double res=0;
  while(f>0){
    fill(dist,dist+V,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<G[v].size();i++){
	  edge &e=G[v][i];
	  if(e.cap>0&&dist[e.to]-(dist[v]+e.cost)>EPS){
	    dist[e.to]=dist[v]+e.cost;
	    prevv[e.to]=v;
	    preve[e.to]=i;
	    update=true;
	  }
	}
      }
    }
    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;
}

vec gauss_jordan(const mat& A,const vec& b){
  int n=A.size();
  mat B(n,vec(n+1));
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)B[i][j]=A[i][j];
  for(int i=0;i<n;i++)B[i][n]=b[i];
  for(int i=0;i<n;i++){
    int pivot=i;
    for(int j=i;j<n;j++)
      if(abs(B[j][i])>abs(B[pivot][i]))pivot=j;
    swap(B[i],B[pivot]);
    if(abs(B[i][i])<EPS)return vec();
    for(int j=i+1;j<=n;j++)B[i][j]/=B[i][i];
    for(int j=0;j<n;j++){
      if(i!=j)
    for(int k=i+1;k<=n;k++)B[j][k]-=B[j][i]*B[i][k];
    }
  }
  vec x(n);
  for(int i=0;i<n;i++)x[i]=B[i][n];
  return x;
}

int main(){
  int T,N,s,t,F,M,d[N_MAX],f[N_MAX];
  cin>>T;
  while(T--){
    cin>>N>>s>>t>>F;
    V=N;
    vec b(N);
    mat A(N,vec(N,0));
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++)cin>>A[i][j];
      cin>>b[i];
    }
    vec r=gauss_jordan(A,b);
    for(int i=0;i<N;i++){
      cin>>M;
      for(int j=0;j<M;j++)cin>>d[j];
      for(int j=0;j<M;j++)cin>>f[j];
      for(int j=0;j<M;j++)
	add_edge(i,d[j],f[j],abs(r[i]-r[d[j]]));
    }
    double ans=min_cost_flow(s,t,F);
    if(ans!=-1)printf("%.8f\n",ans);
    else cout<<"impossible"<<endl;
    for(int i=0;i<N_MAX;i++)G[i].clear();
  }
  return 0;
}
accuracy: 1
time_ms: 330
memory_kb: 2076
final_rank: 5

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define MAX_V 300
#define INF 1e9
const double EPS = 1e-8;
typedef vector<double> vec;
typedef vector<vec> mat;
typedef pair<double,int> P;
 
struct edge{
    int to,cap,rev;
    double cost;
    edge(int to,int cap,int rev,double cost) :
	to(to),cap(cap),rev(rev),cost(cost) {}
};
 
int V;
vector<edge> G[MAX_V];
double dist[MAX_V],h[MAX_V];;
int prevv[MAX_V],preve[MAX_V];
 
void add_edge(int from,int to,int cap,double cost){
    G[from].push_back(edge(to,cap,G[to].size(),cost));
    G[to].push_back(edge(from,0,G[from].size()-1,-cost));
}
 
double min_cost_flow(int s,int t,int f){
    double res = 0;
    fill(h,h+V,0);
    while(f > 0){
	priority_queue<P,vector<P>,greater<P> > Q;
	fill(dist,dist+V,INF);
	dist[s] = 0;
	Q.push(P(0,s));
	while(!Q.empty()){
	    P p = Q.top(); Q.pop();
	    int v = p.second;
	    if(dist[v] < p.first) 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 + h[v] - h[e.to] + EPS){
		    dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
		    prevv[e.to] = v;
		    preve[e.to] = i;
		    Q.push(P(dist[e.to],e.to));
		}
	    }
	}
	if(dist[t] == INF){
	    return -1;
	}
	for(int v = 0 ; v < V ; v++){
	    h[v] += dist[v];
	}
	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.rev].cap += d;
	}
    }
    return res;
}
 
vec gauss_jordan(const mat &A,const vec &b){
    int n = A.size();
    mat B(n,vec(n+1));
    for(int i = 0 ; i < n ; i++){
	for(int j = 0 ; j < n ; j++){
	    B[i][j] = A[i][j];
	}
    }
    for(int i = 0 ; i < n ; i++){
	B[i][n] = b[i];
    }
    for(int i = 0 ; i < n ; i++){
	int pivot = i;
	for(int j = i ; j < n ; j++){
	    if(abs(B[j][i]) > abs(B[pivot][i])){
		pivot = j;
	    }
	}
	swap(B[i],B[pivot]);
	if(abs(B[i][i]) < EPS) return vec();
	for(int j = i+1 ; j <= n ; j++){
	    B[i][j] /= B[i][i];
	}
	for(int j = 0 ; j < n ; j++){
	    if(i != j){
		for(int k = i+1 ; k <= n ; k++){
		    B[j][k] -= B[j][i]*B[i][k];
		}
	    }
	}
    }
    vec x(n);
    for(int i = 0 ; i < n ; i++){
	x[i] = B[i][n];
    }
    return x;
}
 
void init(){
    for(int i = 0 ; i < MAX_V ; i++){
	G[i].clear();
    }
}
 
int main(){
    int Tc;
    cin >> Tc;
    while(Tc--){
	int N,s,t,F;
	init();
	cin >> N >> s >> t >> F;
	mat a(N,vec(N)); vec c(N);
	for(int i = 0 ; i < N ; i++){
	    for(int j = 0 ; j < N ; j++){
		cin >> a[i][j];
	    }
	    cin >> c[i];
	}
	vec res = gauss_jordan(a,c);
	for(int i = 0 ; i < N ; i++){
	    int M,d[N],f;
	    cin >> M;
	    for(int j = 0 ; j < M ; j++){
		cin >> d[j];
	    }
	    for(int j = 0 ; j < M ; j++){
		cin >> f;
		add_edge(i,d[j],f,abs(res[i]-res[d[j]]));
	    }
	}
	V = N;
	double ans = min_cost_flow(s,t,F);
	if(ans == -1){
	    printf("impossible\n");
	}else{
	    printf("%.6f\n",ans);
	}
    }
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 3828
final_rank: 10

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

using namespace std;

#define REP(i,a,b) for(int i=a;i<(int)b;i++)
#define rep(i,n) REP(i,0,n)

typedef long double D;

struct edge { int to; D cap, cost; int rev; };
//int const INF = 1<<29;
double const Inf = 1e40;
int const Max = 300;
D h[Max], dist[Max];
int prevv[Max], preve[Max];

int V;

vector<edge> G[Max];

inline void add_edge(int f, int t, D cap, D cost) {
  G[f].push_back((edge){t, cap, cost, (int)G[t].size()});
  G[t].push_back((edge){f, 0, -cost, (int)G[f].size()-1});
}

double const INF = 1e40;
long double const EPS = 1e-5;

typedef pair<D, int> P;

D min_cost_flow(int S, int T, D f) {
  D ret = 0;
  fill(h, h+V, 0);
  while(f > 0) {
    priority_queue<P, vector<P>, greater<P> > pq;
    fill(dist, dist+V, INF);
    dist[S] = 0;
    pq.push(P(0, S));
    while(!pq.empty()) {
      D cost = pq.top().first;
      int curr = pq.top().second; pq.pop();
      if(dist[curr] < cost) { continue; }
      rep(i, G[curr].size()) {
	edge& e = G[curr][i];
	if(e.cap > EPS && dist[e.to] > dist[curr] + e.cost + h[curr] - h[e.to] + EPS) {
	  dist[e.to] = dist[curr] + e.cost + h[curr] - h[e.to];
	  prevv[e.to] = curr;
	  preve[e.to] = i;
	  pq.push(P(dist[e.to], e.to));
	}
      }
    }
    
    if(dist[T] == INF) { return -1; }
    
    rep(i, V) h[i] += dist[i];
    
    D d = f;
    for(int v = T; v!=S; v=prevv[v]) {
      d = min(d, G[prevv[v]][preve[v]].cap);
    }
    
    f -= d;
    ret += 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 ret;
}

template<class T>
vector<T> gauss_jordan(vector<vector<T> > const& A, vector<T> const& b) {
  int N = A.size();
  vector<vector<T> > B(A);
  rep(i, B.size()) B[i].resize(N+1);
  rep(i, N) B[i][N] = b[i];
  rep(i, N) {
    int pivot = i;
    REP(j, i, N) {
      if(abs(B[pivot][i]) < abs(B[j][i])) {
	pivot = j;
      }
    }
    swap(B[i], B[pivot]);
    
    if(abs(B[i][i]) < EPS) { return vector<T>(); }
    
    REP(j, i+1, N+1) { B[i][j] /= B[i][i]; }
    rep(j, N) if(i != j) {
      REP(k, i+1, N+2) B[j][k] -= B[j][i] * B[i][k];
    }
  }
  vector<T> x(N);
  rep(i, N) x[i] = B[i][N];
  return x;
}

typedef vector<D> Vec;
typedef vector<Vec> Mat;

int main() {
  
  int Tc; cin >> Tc;
  while(Tc--) {
    int N, s, t; D F; cin >> N >> s >> t >> F;
    V = N;
    rep(i, N) G[i].clear();
    
    Mat A(N, Vec(N)); Vec b(N);
    rep(i, N) {
      rep(j, N) {
	cin >> A[i][j];
      }
      cin >> b[i];
    }
    
    Vec X(gauss_jordan(A, b));
    
    rep(i, N) {
      int M; cin >> M;
      vector<int> ds(M);
      rep(j, M) { cin >> ds[j]; }
      rep(j, M) {
	D f; cin >> f;
	//	cerr << i << " -> " << ds[j] << endl;
	add_edge(i, ds[j], f, abs(X[i]-X[ds[j]]));
      }
    }
    
    D r = min_cost_flow(s, t, F);
    if(r < EPS) {
      cout << "impossible\n";
    }
    else {
      printf("%.10Lf\n", r);
    }
  }
  
  return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 3376
final_rank: 8

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

using namespace std;

#define MAX_V 300
#define INF 1e9
const double EPS = 1e-8;
typedef vector<double> vec;
typedef vector<vec> mat;
typedef pair<double,int> P;

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

int V;
vector<edge> G[MAX_V];
double dist[MAX_V],h[MAX_V];;
int prevv[MAX_V],preve[MAX_V];

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

double min_cost_flow(int s,int t,int f){
  double res = 0;
  fill(h,h+V,0);
  while(f > 0){
    priority_queue<P,vector<P>,greater<P> > Q;
    fill(dist,dist+V,INF);
    dist[s] = 0;
    Q.push(P(0,s));
    while(!Q.empty()){
      P p = Q.top(); Q.pop();
      int v = p.second;
      if(dist[v] < p.first) 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 + h[v] - h[e.to] + EPS){
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          Q.push(P(dist[e.to],e.to));
        }
      }
    }
    if(dist[t] == INF){
      return -1;
    }
    for(int v = 0 ; v < V ; v++){
      h[v] += dist[v];
    }
    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.rev].cap += d;
    }
  }
  return res;
}

vec gauss_jordan(const mat &A,const vec &b){
  int n = A.size();
  mat B(n,vec(n+1));
  for(int i = 0 ; i < n ; i++){
    for(int j = 0 ; j < n ; j++){
      B[i][j] = A[i][j];
    }
  }
  for(int i = 0 ; i < n ; i++){
    B[i][n] = b[i];
  }
  for(int i = 0 ; i < n ; i++){
    int pivot = i;
    for(int j = i ; j < n ; j++){
      if(abs(B[j][i]) > abs(B[pivot][i])){
        pivot = j;
      }
    }
    swap(B[i],B[pivot]);
    if(abs(B[i][i]) < EPS) return vec();
    for(int j = i+1 ; j <= n ; j++){
      B[i][j] /= B[i][i];
    }
    for(int j = 0 ; j < n ; j++){
      if(i != j){
        for(int k = i+1 ; k <= n ; k++){
          B[j][k] -= B[j][i]*B[i][k];
        }
      }
    }
  }
  vec x(n);
  for(int i = 0 ; i < n ; i++){
    x[i] = B[i][n];
  }
  return x;
}

void init(){
  for(int i = 0 ; i < MAX_V ; i++){
    G[i].clear();
  }
}

int main(){
  int Tc;
  cin >> Tc;
  while(Tc--){
    int N,s,t,F;
    init();
    cin >> N >> s >> t >> F;
    mat a(N,vec(N)); vec c(N);
    for(int i = 0 ; i < N ; i++){
      for(int j = 0 ; j < N ; j++){
        cin >> a[i][j];
      }
      cin >> c[i];
    }
    vec res = gauss_jordan(a,c);
    for(int i = 0 ; i < N ; i++){
      int M,d[N],f;
      cin >> M;
      for(int j = 0 ; j < M ; j++){
        cin >> d[j];
      }
      for(int j = 0 ; j < M ; j++){
        cin >> f;
        add_edge(i,d[j],f,abs(res[i]-res[d[j]]));
      }
    }
    V = N;
    double ans = min_cost_flow(s,t,F);
    if(ans == -1){
      printf("impossible\n");
    }else{
      printf("%.6f\n",ans);
    }
  }
  return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 2052
final_rank: 1

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-8)
#define equals(a,b) (fabs((a)-(b))<EPS)
 
using namespace std;
 
typedef pair<int,int> ii;
 
bool LT(double a,double b) { return !equals(a,b) && a < b ; }
 
struct Edge {
  int to,cap;
  double cost;
  int rev;
};
 
const int MAX_V = 1000, IINF = INT_MAX;
int V;
vector<Edge> G[MAX_V];
 
double h[MAX_V],dist[MAX_V];//////// fpwjefoajfpojeawfopefa
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,int f){
  double res = 0;
  fill(h,h+V,0);
  while(LT(0,f)){
    priority_queue<ii,vector<ii>,greater<ii> > Q;
    fill(dist,dist+V,INT_MAX);
    dist[s] = 0;
    Q.push(ii(0,s));
    while( !Q.empty() ){
      ii p = Q.top(); Q.pop();
      int v = p.second;
      if( LT(dist[v],p.first) ) continue;
      for(int i=0;i<G[v].size();i++)      {
    Edge &e = G[v][i];
    if( LT(0,e.cap) && LT(dist[v]+e.cost+h[v]-h[e.to],dist[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( equals(dist[t],INT_MAX) ) return -1;
    rep(v,V) h[v] += dist[v];
    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.rev].cap += d;
    }
  }
  return res;
}
 
typedef vector<double> vd;
typedef vector<vd> mat;
 
 
 
vector<double> f(const mat& A,const vd& b){
  int n = A.size();
  mat B(n,vd(n+1));
  rep(i,n) rep(j,n) B[i][j] = A[i][j];
  rep(i,n) B[i][n] = b[i];
 
  rep(i,n){
    int pivot = i;
    REP(j,i,n) if( LT(abs(B[pivot][i]),abs(B[j][i])) ) pivot = j;
    swap(B[i],B[pivot]);
    if( abs(B[i][i]) < EPS ) return vd();
    REP(j,i+1,n+1) B[i][j] /= B[i][i];
    rep(j,n){
      if( i != j ){
    REP(k,i+1,n+1) B[j][k] -= B[j][i] * B[i][k];
      }
    }
  }  
 
  vd x(n);
  rep(i,n) x[i] = B[i][n];
  return x;
}
 
void init(int size=MAX_V){
  rep(i,size) G[i].clear();
}
 
int main(){
  int T;
  cin >> T;
  while( T-- ){
    int N,s,t,F;
    cin >> N >> s >> t >> F;
    mat A(N,vector<double>(N,0));
    vector<double> b(N,0);
    rep(i,N) {
      rep(j,N) {
    cin >> A[i][j];
      }
      cin >> b[i];
    }
     
    vector<double> ans = f(A,b);
     
    init();
 
    rep(i,N) {
      int M;
      cin >> M;
      vector<ii> vec(M);
      rep(j,M) cin >> vec[j].first;
      rep(j,M) cin >> vec[j].second;
      rep(j,M) {
    add_edge(i,vec[j].first,vec[j].second,abs(ans[i]-ans[vec[j].first]));
      }
    }
 
    V = N;
    double temp = min_cost_flow(s,t,F);
    if( equals(temp,-1) ) puts("impossible");
    else printf("%.10f\n",temp);
 
  }
  return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 2076
final_rank: 6

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-8)
#define equals(a,b) (fabs((a)-(b))<EPS)

using namespace std;

typedef pair<int,int> ii;

bool LT(double a,double b) { return !equals(a,b) && a < b ; }

struct Edge {
  int to,cap;
  double cost;
  int rev;
};

const int MAX_V = 1000, IINF = INT_MAX;
int V;
vector<Edge> G[MAX_V];

double h[MAX_V],dist[MAX_V];//////// fpwjefoajfpojeawfopefa
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,int f){
  double res = 0;
  fill(h,h+V,0);
  while(LT(0,f)){
    priority_queue<ii,vector<ii>,greater<ii> > Q;
    fill(dist,dist+V,INT_MAX);
    dist[s] = 0;
    Q.push(ii(0,s));
    while( !Q.empty() ){
      ii p = Q.top(); Q.pop();
      int v = p.second;
      if( LT(dist[v],p.first) ) continue;
      for(int i=0;i<G[v].size();i++)      {
	Edge &e = G[v][i];
	if( LT(0,e.cap) && LT(dist[v]+e.cost+h[v]-h[e.to],dist[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( equals(dist[t],INT_MAX) ) return -1;
    rep(v,V) h[v] += dist[v];
    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.rev].cap += d;
    }
  }
  return res;
}

typedef vector<double> vd;
typedef vector<vd> mat;



vector<double> f(const mat& A,const vd& b){
  int n = A.size();
  mat B(n,vd(n+1));
  rep(i,n) rep(j,n) B[i][j] = A[i][j];
  rep(i,n) B[i][n] = b[i];

  rep(i,n){
    int pivot = i;
    REP(j,i,n) if( LT(abs(B[pivot][i]),abs(B[j][i])) ) pivot = j;
    swap(B[i],B[pivot]);
    if( abs(B[i][i]) < EPS ) return vd();
    REP(j,i+1,n+1) B[i][j] /= B[i][i];
    rep(j,n){
      if( i != j ){
	REP(k,i+1,n+1) B[j][k] -= B[j][i] * B[i][k];
      }
    }
  }  

  vd x(n);
  rep(i,n) x[i] = B[i][n];
  return x;
}

void init(int size=MAX_V){
  rep(i,size) G[i].clear();
}

int main(){
  int T;
  cin >> T;
  while( T-- ){
    int N,s,t,F;
    cin >> N >> s >> t >> F;
    mat A(N,vector<double>(N,0));
    vector<double> b(N,0);
    rep(i,N) {
      rep(j,N) {
	cin >> A[i][j];
      }
      cin >> b[i];
    }
    
    vector<double> ans = f(A,b);
    
    init();

    rep(i,N) {
      int M;
      cin >> M;
      vector<ii> vec(M);
      rep(j,M) cin >> vec[j].first;
      rep(j,M) cin >> vec[j].second;
      rep(j,M) {
	add_edge(i,vec[j].first,vec[j].second,abs(ans[i]-ans[vec[j].first]));
      }
    }

    V = N;
    double temp = min_cost_flow(s,t,F);
    if( equals(temp,-1) ) puts("impossible");
    else printf("%.10f\n",temp);

  }
  return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 2076
final_rank: 6

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

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C,typename=decltype(begin(C()))>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-3;

bool GaussJordan(const vvd& _a,const vd& b,vd& x)
{
	int n=_a.size();
	vvd a(n,vd(n+1));
	rep(i,n){
		copy(all(_a[i]),begin(a[i]));
		a[i][n]=b[i];
	}
	
	rep(i,n){
		int p=i;
		repi(j,i+1,n) if(abs(a[p][i])<abs(a[j][i])) p=j;
		if(abs(a[p][i])<EPS) return false;
		swap(a[i],a[p]);
		peri(j,i,n+1) a[i][j]/=a[i][i];
		rep(j,n) if(j!=i) peri(k,i,n+1) a[j][k]-=a[j][i]*a[i][k];
	}
	
	rep(i,n) x[i]=a[i][n];
	return true;
}

struct Edge{
	int src,dst;
	double cost;
	int cap,flow;
	Edge(){}
	Edge(int s,int d,double co,int ca=0,int f=0):src(s),dst(d),cost(co),cap(ca),flow(f){}
};
bool operator<(const Edge& a,const Edge& b){return a.cost<b.cost;}
bool operator>(const Edge& a,const Edge& b){return a.cost>b.cost;}
struct Graph{
	vector<Edge> es;
	vi head,next;
	Graph(){}
	Graph(int n):head(n,-1){}
	// コスト:-co,容量:0の逆辺も追加する
	void AddEdge(int u,int v,double co,int ca){
		es.emplace_back(u,v,co,ca); next.push_back(head[u]); head[u]=es.size()-1;
		es.emplace_back(v,u,-co,0); next.push_back(head[v]); head[v]=es.size()-1;
	}
};

double MinCostFlow(Graph& g,int tap,int sink,int flow)
{
	int n=g.head.size();
	
	double res=0;
	vd pots(n);
	while(flow>EPS){
		vd cost(n,INF);
		vi prev(n,-1);
		priority_queue<Edge,vector<Edge>,greater<Edge>> pq;
		pq.emplace(-1,tap,0);
		while(pq.size()){
			Edge cur=pq.top(); pq.pop();
			if(cur.cost>cost[cur.dst]-EPS) continue;
			cost[cur.dst]=cur.cost;
			prev[cur.dst]=cur.src;
			for(int i=g.head[cur.dst];i!=-1;i=g.next[i]){
				Edge e=g.es[i];
				if(e.cap-e.flow==0) continue;
				pq.emplace(i,e.dst,cost[e.src]+e.cost+pots[e.src]-pots[e.dst]);
			}
		}
		
		if(cost[sink]==INF) return -1;
		rep(i,n) pots[i]+=cost[i];
		
		int augment=flow;
		for(int v=sink;v!=tap;v=g.es[prev[v]].src){
			Edge e=g.es[prev[v]];
			augment=min(augment,e.cap-e.flow);
		}
		if(augment<EPS) return -1;
		for(int v=sink;v!=tap;v=g.es[prev[v]].src){
			int i=prev[v];
			g.es[i].flow+=augment;
			g.es[i^1].flow-=augment;
		}
		flow-=augment;
		res+=augment*pots[sink];
	}
	
	return res;
}

void solve()
{
	int n,s,t,f; scanf("%d%d%d%d",&n,&s,&t,&f);
	vd cs(n);
	{
		vvd a(n,vd(n));
		vd b(n);
		rep(i,n){
			rep(j,n) scanf("%lf",&a[i][j]);
			scanf("%lf",&b[i]);
		}
		GaussJordan(a,b,cs);
	}
	Graph g(n);
	rep(i,n){
		int m; scanf("%d",&m);
		vi ds(m),fs(m);
		rep(j,m) scanf("%d",&ds[j]);
		rep(j,m) scanf("%d",&fs[j]);
		rep(j,m) g.AddEdge(i,ds[j],abs(cs[ds[j]]-cs[i]),fs[j]);
	}
	double res=MinCostFlow(g,s,t,f);
	if(res==-1)
		puts("impossible");
	else
		printf("%.10f\n",res);
}

int main()
{
	int tc; scanf("%d",&tc);
	rep(_,tc) solve();
}
accuracy: 1
time_ms: 2920
memory_kb: 2700
final_rank: 18

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

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C,typename=decltype(begin(C()))>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

bool GaussJordan(const vvd& _a,const vd& b,vd& x)
{
	int n=_a.size();
	vvd a(n,vd(n+1));
	rep(i,n){
		copy(all(_a[i]),begin(a[i]));
		a[i][n]=b[i];
	}
	
	rep(i,n){
		int p=i;
		repi(j,i+1,n) if(abs(a[p][i])<abs(a[j][i])) p=j;
		if(abs(a[p][i])<EPS) return false;
		swap(a[i],a[p]);
		peri(j,i,n+1) a[i][j]/=a[i][i];
		rep(j,n) if(j!=i) peri(k,i,n+1) a[j][k]-=a[j][i]*a[i][k];
	}
	
	rep(i,n) x[i]=a[i][n];
	return true;
}

struct Edge{
	int src,dst;
	double cost;
	int cap,flow;
	Edge(){}
	Edge(int s,int d,double co,int ca=0,int f=0):src(s),dst(d),cost(co),cap(ca),flow(f){}
};
bool operator<(const Edge& a,const Edge& b){return a.cost<b.cost;}
bool operator>(const Edge& a,const Edge& b){return a.cost>b.cost;}
struct Graph{
	vector<Edge> es;
	vi head,next;
	Graph(){}
	Graph(int n):head(n,-1){}
	// コスト:-co,容量:0の逆辺も追加する
	void AddEdge(int u,int v,double co,int ca){
		es.emplace_back(u,v,co,ca); next.push_back(head[u]); head[u]=es.size()-1;
		es.emplace_back(v,u,-co,0); next.push_back(head[v]); head[v]=es.size()-1;
	}
};

double MinCostFlow(Graph& g,int tap,int sink,int flow)
{
	int n=g.head.size();
	
	double res=0;
	vd pots(n);
	while(flow>EPS){
		vd cost(n,INF);
		vi prev(n,-1);
		priority_queue<Edge,vector<Edge>,greater<Edge>> pq;
		pq.emplace(-1,tap,0);
		while(pq.size()){
			Edge cur=pq.top(); pq.pop();
			if(cur.cost>cost[cur.dst]-EPS) continue;
			cost[cur.dst]=cur.cost;
			prev[cur.dst]=cur.src;
			for(int i=g.head[cur.dst];i!=-1;i=g.next[i]){
				Edge e=g.es[i];
				if(e.cap-e.flow==0) continue;
				pq.emplace(i,e.dst,cost[e.src]+e.cost+pots[e.src]-pots[e.dst]);
			}
		}
		
		if(cost[sink]==INF) return -1;
		rep(i,n) pots[i]+=cost[i];
		
		int augment=flow;
		for(int v=sink;v!=tap;v=g.es[prev[v]].src){
			Edge e=g.es[prev[v]];
			augment=min(augment,e.cap-e.flow);
		}
		if(augment<EPS) return -1;
		for(int v=sink;v!=tap;v=g.es[prev[v]].src){
			int i=prev[v];
			g.es[i].flow+=augment;
			g.es[i^1].flow-=augment;
		}
		flow-=augment;
		res+=augment*pots[sink];
	}
	
	return res;
}

void solve()
{
	int n,s,t,f; scanf("%d%d%d%d",&n,&s,&t,&f);
	vd cs(n);
	{
		vvd a(n,vd(n));
		vd b(n);
		rep(i,n){
			rep(j,n) scanf("%lf",&a[i][j]);
			scanf("%lf",&b[i]);
		}
		GaussJordan(a,b,cs);
	}
	Graph g(n);
	rep(i,n){
		int m; scanf("%d",&m);
		vi ds(m),fs(m);
		rep(j,m) scanf("%d",&ds[j]);
		rep(j,m) scanf("%d",&fs[j]);
		rep(j,m) g.AddEdge(i,ds[j],abs(cs[ds[j]]-cs[i]),fs[j]);
	}
	double res=MinCostFlow(g,s,t,f);
	if(res==-1)
		puts("impossible");
	else
		printf("%.10f\n",res);
}

int main()
{
	int tc; scanf("%d",&tc);
	rep(_,tc) solve();
}
accuracy: 1
time_ms: 2950
memory_kb: 2700
final_rank: 20

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

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C,typename=decltype(begin(C()))>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

bool GaussJordan(const vvd& _a,const vd& b,vd& x)
{
	int n=_a.size();
	vvd a(n,vd(n+1));
	rep(i,n){
		copy(all(_a[i]),begin(a[i]));
		a[i][n]=b[i];
	}
	
	rep(i,n){
		int p=i;
		repi(j,i+1,n) if(abs(a[p][i])<abs(a[j][i])) p=j;
		if(abs(a[p][i])<EPS) return false;
		swap(a[i],a[p]);
		peri(j,i,n+1) a[i][j]/=a[i][i];
		rep(j,n) if(j!=i) peri(k,i,n+1) a[j][k]-=a[j][i]*a[i][k];
	}
	
	rep(i,n) x[i]=a[i][n];
	return true;
}

struct Edge{
	int src,dst;
	double cost;
	int cap,flow;
	Edge(){}
	Edge(int s,int d,double co,int ca=0,int f=0):src(s),dst(d),cost(co),cap(ca),flow(f){}
};
bool operator<(const Edge& a,const Edge& b){return a.cost<b.cost;}
bool operator>(const Edge& a,const Edge& b){return a.cost>b.cost;}
struct Graph{
	vector<Edge> es;
	vi head,next;
	Graph(){}
	Graph(int n):head(n,-1){}
	// コスト:-co,容量:0の逆辺も追加する
	void AddEdge(int u,int v,double co,int ca){
		es.emplace_back(u,v,co,ca); next.push_back(head[u]); head[u]=es.size()-1;
		es.emplace_back(v,u,-co,0); next.push_back(head[v]); head[v]=es.size()-1;
	}
};

double MinCostFlow(Graph& g,int tap,int sink,int flow)
{
	int n=g.head.size();
	
	double res=0;
	vd pots(n);
	while(flow>EPS){
		vd cost(n,INF);
		vi prev(n,-1);
		priority_queue<Edge,vector<Edge>,greater<Edge>> pq;
		pq.emplace(-1,tap,0);
		while(pq.size()){
			Edge cur=pq.top(); pq.pop();
			if(cur.cost>cost[cur.dst]-EPS) continue;
			cost[cur.dst]=cur.cost;
			prev[cur.dst]=cur.src;
			for(int i=g.head[cur.dst];i!=-1;i=g.next[i]){
				Edge e=g.es[i];
				if(e.cap-e.flow==0) continue;
				pq.emplace(i,e.dst,cost[e.src]+e.cost+pots[e.src]-pots[e.dst]);
			}
		}
		
		if(cost[sink]==INF) return -1;
		rep(i,n) pots[i]+=cost[i];
		
		int augment=flow;
		for(int v=sink;v!=tap;v=g.es[prev[v]].src){
			Edge e=g.es[prev[v]];
			augment=min(augment,e.cap-e.flow);
		}
		if(augment<EPS) return -1;
		for(int v=sink;v!=tap;v=g.es[prev[v]].src){
			int i=prev[v];
			g.es[i].flow+=augment;
			g.es[i^1].flow-=augment;
		}
		flow-=augment;
		res+=augment*pots[sink];
	}
	
	return res;
}

void solve()
{
	int n,s,t,f; cin>>n>>s>>t>>f;
	vd cs(n);
	{
		vvd a(n,vd(n));
		vd b(n);
		rep(i,n){
			rep(j,n) cin>>a[i][j];
			cin>>b[i];
		}
		GaussJordan(a,b,cs);
	}
	Graph g(n);
	rep(i,n){
		int m; cin>>m;
		vi ds(m),fs(m);
		rep(j,m) cin>>ds[j];
		rep(j,m) cin>>fs[j];
		rep(j,m) g.AddEdge(i,ds[j],abs(cs[ds[j]]-cs[i]),fs[j]);
	}
	double res=MinCostFlow(g,s,t,f);
	if(res==-1)
		puts("impossible");
	else
		printf("%.10f\n",res);
}

int main()
{
	int tc; cin>>tc;
	rep(_,tc) solve();
}
accuracy: 1
time_ms: 2910
memory_kb: 2712
final_rank: 19