#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,ssse3,sse3,sse4,popcnt,avx,mmx,abm,tune=native")
#include <bits/stdc++.h>
#define DEBUG 1
using namespace std;

namespace output{
    void __(short x){cout<<x;}
    void __(unsigned x){cout<<x;}
    void __(int x){cout<<x;}
    void __(long long x){cout<<x;}
    void __(unsigned long long x){cout<<x;}
    void __(double x){cout<<x;}
    void __(long double x){cout<<x;}
    void __(char x){cout<<x;}
    void __(const char*x){cout<<x;}
    void __(const string&x){cout<<x;}
    void __(bool x){cout<<(x?"true":"false");}
    template<class S,class T>
    void __(const pair<S,T>&x){__(DEBUG?"(":""),__(x.first),__(DEBUG?", ":" "),__(x.second),__(DEBUG?")":"");}
    template<class T>
    void __(const vector<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const set<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class T>
    void __(const multiset<T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    template<class S,class T>
    void __(const map<S,T>&x){__(DEBUG?"{":"");bool _=0;for(const auto&v:x)__(_?DEBUG?", ":" ":""),__(v),_=1;__(DEBUG?"}":"");}
    void pr(){cout<<"\n";}
    template<class S,class... T>
    void pr(const S&a,const T&...b){__(a);if(sizeof...(b))__(' ');pr(b...);}
}

using namespace output;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,char> pic;
typedef pair<double,double> pdd;
typedef pair<ld,ld> pld;
typedef vector<int> vi;
typedef vector<ll> vl;

#define pb push_back
#define fox(i,x,y) for(int i=(x);i<=(y);i++)
#define foxr(i,x,y) for(int i=(y);i>=(x);i--)

const int MN = 55;
const long double eps = 1e-12;
int N, M, X, i, x, y, w, par[MN], cap[MN][MN]; long double lo, hi;
vector<pii> adj[MN]; vi g[MN]; queue<int> q;

inline void bfs(int st){
    par[st]=0; q.push(st);
    while(q.size()){
        int x = q.front(); q.pop();
        for(auto v : g[x]){
            if(par[v]==-1&&cap[x][v]>0){
                par[v]=x;
                q.push(v);
            }
        }
    }
}

int main(){
    scanf("%d%d%d",&N,&M,&X);
    for(i=1;i<=M;i++){
        scanf("%d%d%d",&x,&y,&w);
        adj[x].pb({y,w});
        g[x].pb(y);
        g[y].pb(x);
    }
    lo=0, hi=min(1e6,M*1e6/X);
    while(lo+eps<hi){
        long double m=(lo+hi)/2;
        memset(cap,0,sizeof(cap));
        memset(par,-1,sizeof(par));
        for(i=1;i<=N;i++){
            for(auto v : adj[i])
                cap[i][v.first]+=floor(v.second/m);
        }
        bfs(1);
        int flow = 0;
        while(par[N]!=-1){
            int cur = N, mn = 1<<30;
            while(par[cur]>0){
                int pre = par[cur];
                mn=min(mn,cap[pre][cur]);
                cur=pre;
            }
            flow += mn;
            cur = N;
            while(par[cur]>0){
                int pre = par[cur];
                cap[pre][cur]-=mn;
                cap[cur][pre]+=mn;
                cur=pre;
            }
            if(flow>=X) break;
            else{
                memset(par,-1,sizeof(par));
                bfs(1);
            }
        }
        if(flow>=X) lo=m+eps;
        else hi=m;
    }
    printf("%.8Lf\n",lo*X);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
int ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v;
	double cap;
}eg[510];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, int spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0;
}
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		double cap = eg[i].cap;
		c[u][v] = int(1.00*cap/x);
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	int sum = 0;
	for(auto v: vi[1]) if(f[1][v] >= 0) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%lf", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = oo*1.00;
	double step = 0.00000000001;
	while(l + step < r)	{
		double mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid - step;
	}
	double ans = 0.00;
	if(check(l)) ans = 1.00 * l * k;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
int ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v;
	double cap;
}eg[510];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, int spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0;
}
const double ESP = 1e-9, esp = 1e-11;
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		double k = (double)eg[i].cap / x;
		int kk = (int)k;
		if ((double)kk + 1 - k <= (double)ESP) kk++;
		c[u][v] = kk;
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	int sum = 0;
	for(auto v: vi[1]) if(f[1][v] >= 0) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%lf", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = oo*1.00;
	while(l + esp < r)	{
		double mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid - esp;
	}
	double ans = 0.00;
	if(check(l)) ans = 1.00 * l * k;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
int ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v;
	double cap;
}eg[510];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, int spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0;
}
const double ESP = 1e-9, esp = 1e-11;
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		double cap = eg[i].cap * 1.00 / x;
		int kk = eg[i].cap / x;
		if(double(kk + 1) - cap <= ESP) kk ++;
		c[u][v] = floor(eg[i].cap * 1.00 / x);
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	int sum = 0;
	for(auto v: vi[1]) if(f[1][v] >= 0) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%lf", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = oo*1.00;
	while(l + esp < r)	{
		double mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid - esp;
	}
	double ans = 0.00;
	if(check(l)) ans = 1.00 * l * k;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
int ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v;
	double cap;
}eg[510];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, int spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0;
}
const double ESP = 1e-9, esp = 1e-11;
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		double cap = eg[i].cap * 1.00 / x;
		int kk = eg[i].cap / x;
		if(cap - kk <= ESP) kk ++;
		c[u][v] = floor(eg[i].cap * 1.00 / x);
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	int sum = 0;
	for(auto v: vi[1]) if(f[1][v] >= 0) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%lf", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = oo*1.00;
	while(l + esp < r)	{
		double mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid - esp;
	}
	double ans = 0.00;
	if(check(l)) ans = 1.00 * l * k;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
int ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v;
	double cap;
}eg[510];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, int spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0;
}
bool check(double x)	{
    x *= (100000000.00); x = floor(x);
    x /= (1.00*100000000);
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		double cap = eg[i].cap;
		c[u][v] = floor(1.00*cap/x);
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	int sum = 0;
	for(auto v: vi[1]) if(f[1][v] >= 0) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%lf", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = oo*1.00;
	double step = 0.00000000001;
	while(l + step < r)	{
		double mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid - step;
	}
	double ans = 0.00;
	if(check(l)) ans = 1.00 * l * k;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
long long ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v, cap;
}eg[N];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, long long spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm * 1ll, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0ll;
}
const double EPS = 1e-9;
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		long double k = (long double)eg[i].cap / x;
		long long kk = (long long)k;
		if((double)kk + 1 - k <= (double)EPS) kk ++;
		c[u][v] = kk;
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	long long sum = 0ll;
	for(auto v: vi[1]) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%d", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = 1000000.0;
	for(int i = 1; i <= 100; ++i)	{
		double mid = (l + r) / 2.00;
		if(check(mid)) l = mid;
		else r = mid;
	}
	double ans = 1.00 * k * l;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
int ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v;
	double cap;
}eg[N];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, int spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0;
}
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		double cap = eg[i].cap;
		c[u][v] = int(1.00*cap/x);
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	int sum = 0;
	for(auto v: vi[1]) if(f[1][v] >= 0) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%lf", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = oo*1.00;
	double step = 0.00000000001;
	while(l + step < r)	{
		double mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid - step;
	}
	double ans = 0.00;
	if(check(l)) ans = 1.00 * l * k;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
#define pb push_back
const int N = 70, oo = 1e9;
int n, m, k, ans, ptr[2*N], d[2*N];
long long f[2*N][2*N], c[2*N][2*N];
vector<int> vi[2*N];
struct book {
	int u, v, cap;
}eg[505];
bool bfs()
{
	for(int i = 0; i <= 2*n + 1; ++i) d[i] = oo, ptr[i] = 0;
	d[0] = 0;
	queue<int> pq; pq.push(0);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[2*n + 1] != oo;
}
void add(int u, int v, long long spm){
	f[u][v] += spm; f[v][u] -= spm;
}
long long dfs(int u, long long spm)
{
	//cout << u << ' ' << ptr[u] << " spm check \n";
	if(u == 2*n + 1 || !spm) return spm;
	for(int &i = ptr[u]; i < vi[u].size(); ++i)
	{
		int v = vi[u][i];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			long long nex = dfs(v, min(spm * 1ll, c[u][v] - f[u][v]));
			if(nex) {
				//cout << nex << ' ' << u << ' ' << v << " hieu = " << c[u][v]  << ' '<<  f[u][v] << '\n';
				add(u, v, nex);
				return nex;
			}
		}
	}
	return 0ll;
}
const double EPS = 1e-9;
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		long double k = (long double)eg[i].cap / x;
		long long kk = (long long)k;
		if((double)kk + 1 - k <= (double)EPS) kk ++;
		//cout << "check?? " << kk << ' ' << u << ' ' << v << '\n';
		c[u][v + n] = kk;
	}
	while(bfs()){
//		break;
		while(dfs(0, oo));
	}
//	return false;
	long long sum = 0ll;
	for(int i = 1; i <= n; ++i) sum += f[i + n][2*n + 1];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%d", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v + n);
		vi[eg[i].v + n].push_back(eg[i].u);
	}
	FOR(i, 1, n)	{
		vi[i].pb(i + n); vi[i + n].pb(i);
		c[i + n][i] = oo;
	}
	vi[0].pb(1); vi[1].pb(0);
	c[0][1] = oo;
	vi[2*n].pb(2*n + 1); vi[2*n + 1].pb(2*n);
	c[2*n][2*n + 1] = oo;
	//cout << check(1.00);
	//return 0;
	double l = 0.00, r = 1000000.0;
	for(int i = 1; i <= 100; ++i)	{
		double mid = (l + r) / 2.00;
		if(check(mid)) l = mid;
		else r = mid;
//		break;
	}
	//cout << l << '\n';
	double ans = 1.00 * k * l;
	printf("%.6lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
int ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v;
	double cap;
}eg[510];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, int spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0;
}
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		double cap = eg[i].cap;
		c[u][v] = floor(1.00*cap/x);
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	int sum = 0;
	for(auto v: vi[1]) if(f[1][v] >= 0) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%lf", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = oo*1.00;
	double step = 0.00000000001;
	while(l + step < r)	{
		double mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid - step;
	}
	double ans = 0.00;
	if(check(l)) ans = 1.00 * l * k;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
using namespace std;
#define ii pair<int, int>
#define fi first
#define se second
#define FOR(a, b, c) for(int a = b; a <= c; ++a)
const int N = 70, oo = 1e9;
int n, m, k, ans;
long long ptr[N], d[N], f[N][N], c[N][N];
vector<int> vi[N];
struct book {
	int u, v, cap;
}eg[505];
bool bfs()
{
	for(int i = 1; i <= n; ++i) d[i] = oo, ptr[i] = 0;
	d[1] = 0;
	queue<int> pq; pq.push(1);
	while(!pq.empty())	{
		int u = pq.front(); pq.pop();
		for(int v: vi[u])	if(d[v] == oo && f[u][v] < c[u][v]){
			d[v] = d[u] + 1;	pq.push(v);
		}
	}
	return d[n] != oo;
}
void add(int u, int v, int spm){
	f[u][v] += spm; f[v][u] -= spm;
}
int dfs(int u, long long spm)
{
	if(u == n || !spm) return spm;
	for(; ptr[u] < vi[u].size(); ++ptr[u])
	{
		int v = vi[u][ptr[u]];
		if(d[v] == d[u] + 1 && f[u][v] < c[u][v])	{
			int nex = dfs(v, min(spm * 1ll, c[u][v] - f[u][v]));
			if(nex) {
				add(u, v, nex); return nex;
			}
		}
	}
	return 0ll;
}
const double EPS = 1e-9;
bool check(double x)	{
	memset(f, 0, sizeof f);
	FOR(i, 1, m)	{
		int u = eg[i].u, v = eg[i].v;
		long double k = (long double)eg[i].cap / x;
		long long kk = (long long)k;
		if((double)kk + 1 - k <= (double)EPS) kk ++;
		c[u][v] = kk;
	}
	while(bfs()){
		while(dfs(1, oo));
	}
	long long sum = 0ll;
	for(auto v: vi[1]) sum += f[1][v];
	//cout << sum << '\n';
	return (sum >= k);
}
int main() {
	//freopen("test.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	FOR(i, 1, m) 	{
		scanf("%d%d%d", &eg[i].u, &eg[i].v, &eg[i].cap);
		vi[eg[i].u].push_back(eg[i].v);
		vi[eg[i].v].push_back(eg[i].u);
	}

	//cout << check(0.5);
	//return 0;
	double l = 0.00, r = 1000000.0;
	for(int i = 1; i <= 100; ++i)	{
		double mid = (l + r) / 2.00;
		if(check(mid)) l = mid;
		else r = mid;
	}
	double ans = 1.00 * k * l;
	printf("%.10lf", ans);
}


#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define pss pair<short,short>
#define piii  pair<pii,int>
#define vii vector<pair<int,int> >
#define st first
#define nd second
const int mod=1000000007;
const int inf=1000000009;
const long long int INF=1000000000000000009;
const double eps=0.000000000001;
using namespace std;
struct edge
{
    int b,cap;
    double flow;
};
double C;
int N,s,t;
vector<edge> e;
vi P[55];
int d[55],ptr[55];
void add(int a,int b,int c)
{
    edge e1= {b,c,0};
    edge e2= {a,0,0};
    P[a].pb(e.size());
    e.pb(e1);
    P[b].pb(e.size());
    e.pb(e2);
}
bool bfs()
{
    for(int i=1; i<=N; i++)
        d[i]=-1;
    d[s]=0;
    queue<int> K;
    K.push(s);
    while(!K.empty()&&d[t]==-1)
    {
        int u=K.front();
        K.pop();
        for(auto v:P[u])
        {
            edge x=e[v];
            if(d[x.b]==-1&&x.flow+C<=x.cap)
            {
                d[x.b]=d[u]+1;
                K.push(x.b);
            }
        }
    }
    return d[t]!=-1;
}
int dfs(int u,int f)
{
    if(u==t)
        return f;
    if(f==0)
        return 0;
    int s=0;
    for(;ptr[u]<P[u].size();ptr[u]++)
    {
        int v=P[u][ptr[u]];
        edge x=e[v];
        if(d[x.b]!=d[u]+1)
            continue;
        int p=dfs(x.b,min(f,(int)(((double)x.cap-x.flow)/C)));
        s+=p;
        f-=p;
        e[v].flow+=C*p;
        e[v^1].flow-=C*p;
        if(f==0)
            break;

    }
    return s;
}
int dinic()
{
    int flow=0;
    while(true)
    {
        if(!bfs())
            break;
        for(int i=1; i<=N; i++)
            ptr[i]=0;
        while(int p=dfs(s,inf))
            flow+=p;
    }
    return flow;
}
int main()
{
    int n,m,x;
    scanf("%d %d %d",&n,&m,&x);
    N=n;
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
    }
    double p=0,k=1000001;
    while(p+eps<k)
    {
        double sr=(p+k)/2;
       // printf("%f\n",sr);
        C=sr;
        int w=dinic();
       // printf("%d\n",w);
        if(w>=x)
            p=sr;
        else
            k=sr;
        for(int i=0;i<e.size();i++)
            e[i].flow=0;

    }
    printf("%.8lf",p*x);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define pss pair<short,short>
#define piii  pair<pii,int>
#define vii vector<pair<int,int> >
#define st first
#define nd second
const int mod=1000000007;
const int inf=1000000009;
const long long int INF=1000000000000000009;
const double eps=0.00000001;
using namespace std;
struct edge
{
    int b,cap;
    double flow;
};
double C;
int N,s,t;
vector<edge> e;
vi P[55];
int d[55],ptr[55];
void add(int a,int b,int c)
{
    edge e1= {b,c,0};
    edge e2= {a,0,0};
    P[a].pb(e.size());
    e.pb(e1);
    P[b].pb(e.size());
    e.pb(e2);
}
bool bfs()
{
    for(int i=1; i<=N; i++)
        d[i]=-1;
    d[s]=0;
    queue<int> K;
    K.push(s);
    while(!K.empty()&&d[t]==-1)
    {
        int u=K.front();
        K.pop();
        for(auto v:P[u])
        {
            edge x=e[v];
            if(d[x.b]==-1&&x.flow+C<=x.cap)
            {
                d[x.b]=d[u]+1;
                K.push(x.b);
            }
        }
    }
    return d[t]!=-1;
}
int dfs(int u,int f)
{
    if(u==t)
        return f;
    if(f<=0)
        return 0;
    int s=0;
    for(;ptr[u]<P[u].size();ptr[u]++)
    {
        int v=P[u][ptr[u]];
        edge x=e[v];
        if(d[x.b]!=d[u]+1)
            continue;
        int p=dfs(x.b,min(f,(int)(((double)x.cap-x.flow)/C)));
        s+=p;
        f-=p;
        e[v].flow+=p;
        e[v^1].flow-=p;
        if(f==0)
            break;

    }
    return s;
}
int dinic()
{
    int flow=0;
    while(true)
    {
        if(!bfs())
            break;
        for(int i=1; i<=N; i++)
            ptr[i]=0;
        while(int p=dfs(s,inf))
            flow+=p;
    }
    return flow;
}
int main()
{
    int n,m,x;
    scanf("%d %d %d",&n,&m,&x);
    N=n;
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
    }
    double p=0,k=1000001;
    while(p+eps<k)
    {
        double sr=(p+k)/2;
        C=sr;
        if(dinic()>=x)
            p=sr;
        else
            k=sr;
        for(int i=0;i<e.size();i++)
            e[i].flow=0;

    }
    printf("%.8lf",p*x);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define pss pair<short,short>
#define piii  pair<pii,int>
#define vii vector<pair<int,int> >
#define st first
#define nd second
const int mod=1000000007;
const int inf=1000000009;
const long long int INF=1000000000000000009;
const long double eps=0.0000000001;
using namespace std;
struct edge
{
    int b,cap;
    long double flow;
};
int X;
long double C;
int N,s,t;
vector<edge> e;
vi P[55];
int d[55],ptr[55];
void add(int a,int b,int c)
{
    edge e1= {b,c,0};
    edge e2= {a,0,0};
    P[a].pb(e.size());
    e.pb(e1);
    P[b].pb(e.size());
    e.pb(e2);
}
bool bfs()
{
    for(int i=1; i<=N; i++)
        d[i]=-1;
    d[s]=0;
    queue<int> K;
    K.push(s);
    while(!K.empty()&&d[t]==-1)
    {
        int u=K.front();
        K.pop();
        for(auto v:P[u])
        {
            edge x=e[v];
            if(d[x.b]==-1&&x.flow+C<=(long double)x.cap)
            {
                d[x.b]=d[u]+1;
                K.push(x.b);
            }
        }
    }
    return d[t]!=-1;
}
int dfs(int u,int f)
{
    if(u==t)
        return f;
    if(f==0)
        return 0;
    int s=0;
    for(;ptr[u]<P[u].size();ptr[u]++)
    {
        int v=P[u][ptr[u]];
        edge x=e[v];
        if(d[x.b]!=d[u]+1)
            continue;
        int p=dfs(x.b,min(f,(int)(((long double)x.cap-x.flow)/C)));
        s+=p;
        f-=p;
        e[v].flow+=C*p;
        e[v^1].flow-=C*p;
        if(f==0)
            break;

    }
    return s;
}
int dinic()
{
    int flow=0;
    while(true)
    {
        if(!bfs())
            break;
       // printf("jestem\n");
        for(int i=1; i<=N; i++)
            ptr[i]=0;
        while(int p=dfs(s,inf))
        {
            if(flow>=X)
                return flow;
            flow+=p;
        }

    }
    return flow;
}
int main()
{
    int n,m,x;
    X=x;
    scanf("%d %d %d",&n,&m,&x);
    N=n;
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
    }
    long double p=0,k=1000005;
    while(p+eps<k)
    {
        long double sr=(p+k)/2;
       // printf("%Lf\n",sr);
        C=sr;
        int w=dinic();
       // printf("%d\n",w);
        if(w>=x)
            p=sr;
        else
            k=sr;
        for(int i=0;i<e.size();i++)
            e[i].flow=0;
    }
    printf("%.8Lf",p*x);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define pss pair<short,short>
#define piii  pair<pii,int>
#define vii vector<pair<int,int> >
#define st first
#define nd second
const int mod=1000000007;
const int inf=1000000009;
const long long int INF=1000000000000000009;
const long double eps=0.000000000001;
using namespace std;
struct edge
{
    int b,cap;
    long double flow;
};
long double C;
int N,s,t;
vector<edge> e;
vi P[55];
int d[55],ptr[55];
void add(int a,int b,int c)
{
    edge e1= {b,c,0};
    edge e2= {a,0,0};
    P[a].pb(e.size());
    e.pb(e1);
    P[b].pb(e.size());
    e.pb(e2);
}
bool bfs()
{
    for(int i=1; i<=N; i++)
        d[i]=-1;
    d[s]=0;
    queue<int> K;
    K.push(s);
    while(!K.empty()&&d[t]==-1)
    {
        int u=K.front();
        K.pop();
        for(auto v:P[u])
        {
            edge x=e[v];
            if(d[x.b]==-1&&x.flow+C<=x.cap)
            {
                d[x.b]=d[u]+1;
                K.push(x.b);
            }
        }
    }
    return d[t]!=-1;
}
int dfs(int u,int f)
{
    if(u==t)
        return f;
    if(f==0)
        return 0;
    int s=0;
    for(;ptr[u]<P[u].size();ptr[u]++)
    {
        int v=P[u][ptr[u]];
        edge x=e[v];
        if(d[x.b]!=d[u]+1)
            continue;
        int p=dfs(x.b,min(f,(int)(((long double)x.cap-x.flow)/C)));
        s+=p;
        f-=p;
        e[v].flow+=C*p;
        e[v^1].flow-=C*p;
        if(f==0)
            break;

    }
    return s;
}
int dinic()
{
    int flow=0;
    while(true)
    {
        if(!bfs())
            break;
        for(int i=1; i<=N; i++)
            ptr[i]=0;
        while(int p=dfs(s,inf))
            flow+=p;
    }
    return flow;
}
int main()
{
    int n,m,x;
    scanf("%d %d %d",&n,&m,&x);
    N=n;
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
    }
    long double p=0,k=1000001;
    while(p+eps<k)
    {
        long double sr=(p+k)/2;
       // printf("%f\n",sr);
        C=sr;
        int w=dinic();
       // printf("%d\n",w);
        if(w>=x)
            p=sr;
        else
            k=sr;
        for(int i=0;i<e.size();i++)
            e[i].flow=0;

    }
    printf("%.8Lf",p*x);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define pss pair<short,short>
#define piii  pair<pii,int>
#define vii vector<pair<int,int> >
#define st first
#define nd second
const int mod=1000000007;
const int inf=1000000009;
const long long int INF=1000000000000000009;
const long double eps=0.000000000001;
using namespace std;
struct edge
{
    int b,cap;
    long double flow;
};
int X;
long double C;
int N,s,t;
vector<edge> e;
vi P[55];
int d[55],ptr[55];
void add(int a,int b,int c)
{
    edge e1= {b,c,0};
    edge e2= {a,0,0};
    P[a].pb(e.size());
    e.pb(e1);
    P[b].pb(e.size());
    e.pb(e2);
}
bool bfs()
{
    for(int i=1; i<=N; i++)
        d[i]=-1;
    d[s]=0;
    queue<int> K;
    K.push(s);
    while(!K.empty()&&d[t]==-1)
    {
        int u=K.front();
        K.pop();
        for(auto v:P[u])
        {
            edge x=e[v];
            if(d[x.b]==-1&&x.flow+C<=(long double)x.cap)
            {
                d[x.b]=d[u]+1;
                K.push(x.b);
            }
        }
    }
    return d[t]!=-1;
}
int dfs(int u,int f)
{
    if(u==t)
        return f;
    if(f==0)
        return 0;
    int s=0;
    for(;ptr[u]<P[u].size();ptr[u]++)
    {
        int v=P[u][ptr[u]];
        edge x=e[v];
        if(d[x.b]!=d[u]+1)
            continue;
        int p=dfs(x.b,min(f,(int)(((long double)x.cap-x.flow)/C)));
        s+=p;
        f-=p;
        e[v].flow+=C*p;
        e[v^1].flow-=C*p;
        if(f==0)
            break;

    }
    return s;
}
int dinic()
{
    int flow=0;
    while(true)
    {
        if(!bfs())
            break;
       // printf("jestem\n");
        for(int i=1; i<=N; i++)
            ptr[i]=0;
        while(int p=dfs(s,inf))
        {
            if(flow>=X)
                return flow;
            flow+=p;
        }

    }
    return flow;
}
int main()
{
    int n,m,x;
    X=x;
    scanf("%d %d %d",&n,&m,&x);
    N=n;
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
    }
    long double p=0,k=1000005;
    while(p+eps<k)
    {
        long double sr=(p+k)/2;
       // printf("%Lf\n",sr);
        C=sr;
        int w=dinic();
       // printf("%d\n",w);
        if(w>=x)
            p=sr;
        else
            k=sr;
        for(int i=0;i<e.size();i++)
            e[i].flow=0;
    }
    printf("%.8Lf",p*x);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define pss pair<short,short>
#define piii  pair<pii,int>
#define vii vector<pair<int,int> >
#define st first
#define nd second
const int mod=1000000007;
const int inf=1000000009;
const long long int INF=1000000000000000009;
const double eps=0.00000001;
using namespace std;
struct edge
{
    int b,cap;
    double flow;
};
double C;
int N,s,t;
vector<edge> e;
vi P[55];
int d[55],ptr[55];
void add(int a,int b,int c)
{
    edge e1= {b,c,0};
    edge e2= {a,0,0};
    P[a].pb(e.size());
    e.pb(e1);
    P[b].pb(e.size());
    e.pb(e2);
}
bool bfs()
{
    for(int i=1; i<=N; i++)
        d[i]=-1;
    d[s]=0;
    queue<int> K;
    K.push(s);
    while(!K.empty()&&d[t]==-1)
    {
        int u=K.front();
        K.pop();
        for(auto v:P[u])
        {
            edge x=e[v];
            if(d[x.b]==-1&&x.flow+C<=x.cap)
            {
                d[x.b]=d[u]+1;
                K.push(x.b);
            }
        }
    }
    return d[t]!=-1;
}
int dfs(int u,int f)
{
    if(u==t)
        return f;
    if(f==0)
        return 0;
    int s=0;
    for(;ptr[u]<P[u].size();ptr[u]++)
    {
        int v=P[u][ptr[u]];
        edge x=e[v];
        if(d[x.b]!=d[u]+1)
            continue;
        int p=dfs(x.b,min(f,(int)(((double)x.cap-x.flow)/C)));
        s+=p;
        f-=p;
        e[v].flow+=C*p;
        e[v^1].flow-=C*p;
        if(f==0)
            break;

    }
    return s;
}
int dinic()
{
    int flow=0;
    while(true)
    {
        if(!bfs())
            break;
        for(int i=1; i<=N; i++)
            ptr[i]=0;
        while(int p=dfs(s,inf))
            flow+=p;
    }
    return flow;
}
int main()
{
    int n,m,x;
    scanf("%d %d %d",&n,&m,&x);
    N=n;
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
    }
    double p=0,k=1000001;
    while(p+eps<k)
    {
        double sr=(p+k)/2;
       // printf("%f\n",sr);
        C=sr;
        int w=dinic();
       // printf("%d\n",w);
        if(w>=x)
            p=sr;
        else
            k=sr;
        for(int i=0;i<e.size();i++)
            e[i].flow=0;

    }
    printf("%.8lf",p*x);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define pss pair<short,short>
#define piii  pair<pii,int>
#define vii vector<pair<int,int> >
#define st first
#define nd second
const int mod=1000000007;
const int inf=1000000009;
const long long int INF=1000000000000000009;
const long double eps=0.0000000001;
using namespace std;
struct edge
{
    int b,cap;
    long double flow;
};
int X;
long double C;
int N,s,t;
vector<edge> e;
vi P[55];
int d[55],ptr[55];
void add(int a,int b,int c)
{
    edge e1= {b,c,0};
    edge e2= {a,0,0};
    P[a].pb(e.size());
    e.pb(e1);
    P[b].pb(e.size());
    e.pb(e2);
}
bool bfs()
{
    for(int i=1; i<=N; i++)
        d[i]=-1;
    d[s]=0;
    queue<int> K;
    K.push(s);
    while(!K.empty()&&d[t]==-1)
    {
        int u=K.front();
        K.pop();
        for(auto v:P[u])
        {
            edge x=e[v];
            if(d[x.b]==-1&&x.flow+C<=(long double)x.cap)
            {
                d[x.b]=d[u]+1;
                K.push(x.b);
            }
        }
    }
    return d[t]!=-1;
}
int dfs(int u,int f)
{
    if(u==t)
        return f;
    if(f==0)
        return 0;
    int s=0;
    for(;ptr[u]<P[u].size();ptr[u]++)
    {
        int v=P[u][ptr[u]];
        edge x=e[v];
        if(d[x.b]!=d[u]+1)
            continue;
        int z;
        if((long double)(x.cap-x.flow)/C>100000)
            z=1000000;
        else
            z=(int)((long double)(x.cap-x.flow)/C);
        int p=dfs(x.b,min(f,z));
        s+=p;
        f-=p;
        e[v].flow+=C*p;
        e[v^1].flow-=C*p;
        if(f==0)
            break;

    }
    return s;
}
int dinic()
{
    int flow=0;
    while(true)
    {
        if(!bfs())
            break;
       // printf("jestem\n");
        for(int i=1; i<=N; i++)
            ptr[i]=0;
        while(int p=dfs(s,inf))
        {
            if(flow>=X)
                return flow;
            flow+=p;
        }

    }
    return flow;
}
int main()
{
    int n,m,x;
    X=x;
    scanf("%d %d %d",&n,&m,&x);
    N=n;
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
    }
    long double p=0,k=1000005;
    while(p+eps<k)
    {
        long double sr=(p+k)/2;
       // printf("%Lf\n",sr);
        C=sr;
        int w=dinic();
       // printf("%d\n",w);
        if(w>=x)
            p=sr;
        else
            k=sr;
        for(int i=0;i<e.size();i++)
            e[i].flow=0;
    }
    printf("%.8Lf",p*x);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int,int>
#define pss pair<short,short>
#define piii  pair<pii,int>
#define vii vector<pair<int,int> >
#define st first
#define nd second
const int mod=1000000007;
const int inf=1000000009;
const long long int INF=1000000000000000009;
const double eps=0.00000001;
using namespace std;
struct edge
{
    int b,cap;
    double flow;
};
double C;
int N,s,t;
vector<edge> e;
vi P[55];
int d[55],ptr[55];
void add(int a,int b,int c)
{
    edge e1= {b,c,0};
    edge e2= {a,0,0};
    P[a].pb(e.size());
    e.pb(e1);
    P[b].pb(e.size());
    e.pb(e2);
}
bool bfs()
{
    for(int i=1; i<=N; i++)
        d[i]=-1;
    d[s]=0;
    queue<int> K;
    K.push(s);
    while(!K.empty()&&d[t]==-1)
    {
        int u=K.front();
        K.pop();
        for(auto v:P[u])
        {
            edge x=e[v];
            if(d[x.b]==-1&&x.flow+C<=x.cap)
            {
                d[x.b]=d[u]+1;
                K.push(x.b);
            }
        }
    }
    return d[t]!=-1;
}
int dfs(int u,int f)
{
    if(u==t)
        return f;
    if(!f)
        return 0;
    int s=0;
    for(;ptr[u]<P[u].size();ptr[u]++)
    {
        int v=P[u][ptr[u]];
        edge x=e[v];
        if(d[x.b]!=d[u]+1)
            continue;
        int p=dfs(x.b,min(f,(int)(((double)x.cap-x.flow)/C)));
        s+=p;
        f-=p;
        e[v].flow+=p;
        e[v^1].flow-=p;
        if(f==0)
            break;

    }
    return s;
}
int dinic()
{
    int flow=0;
    while(true)
    {
        if(!bfs())
            break;
        for(int i=1; i<=N; i++)
            ptr[i]=0;
        while(int p=dfs(s,inf))
            flow+=p;
    }
    return flow;
}
int main()
{
    int n,m,x;
    scanf("%d %d %d",&n,&m,&x);
    N=n;
    s=1,t=n;
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        add(a,b,c);
    }
    double p=0,k=1000001;
    while(p+eps<k)
    {
        double sr=(p+k)/2;
        C=sr;
        if(dinic()>=x)
            p=sr;
        else
            k=sr;
        for(int i=0;i<e.size();i++)
            e[i].flow=0;

    }
    printf("%.8lf",p*x);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool Directed>
class flowNetwork {
    private:
        class Edge {
            public:
                int From;
                int To;
                int Capacity;
                int Flow;

                Edge(
                  int __From = 0,
                  int __To = 0,
                  int __Capacity = 0,
                  int __Flow = 0
                ) {
                    From = __From;
                    To = __To;
                    Capacity = __Capacity;
                    Flow = __Flow;
                }
        };

        int Size;
        int Source;
        int Sink;
        int numEdges;
        vector <Edge> Edges;
        vector <vector <int>> G;
        static const int INF = numeric_limits <int> :: max();

        inline void linkNodes(int x, int y, int c) {
            Edges.push_back(Edge(x, y, c, 0));
            G[x].push_back(numEdges);
            numEdges++;

            Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
            G[y].push_back(numEdges);
            numEdges++;
        }

        pair <bool, vector <int>> findPath() {
            vector <int> Parent(Size, -1);
            queue <int> Q;
            for (Q.push(Source); Q.empty() == false; Q.pop()) {
                int x = Q.front();
                if (x != Sink) {
                    for (int i: G[x]) {
                        if (Edges[i].Flow < Edges[i].Capacity) {
                            int y = Edges[i].To;
                            if (y != Source && Parent[y] == -1) {
                                Parent[y] = i;
                                Q.push(y);
                            }
                        }
                    }
                }
            }
            if (Parent[Sink] != -1) return {true, Parent};
            else return {false, vector <int>()};
        }

    public:
        flowNetwork(
          const int __Size,
          const int __Source,
          const int __Sink,
          const vector <pair <int, pair <int, int>>> &Edges
        ) {
            Size = __Size;
            Source = __Source;
            Sink = __Sink;
            numEdges = 0;
            G = vector <vector <int>>(Size, vector <int>());
            for (const pair <int, pair <int, int>> &Edge: Edges) {
                int x;
                int y;
                int c = Edge.fi;
                tie(x, y) = Edge.se;
                linkNodes(x, y, c);
            }
        }

        int flowSolve() {
            int k = 0;
            int flowSum = 0;
            bool Stop = false;
            do {
                bool foundSolution;
                vector <int> Parent;
                tie(foundSolution, Parent) = findPath();
                if (foundSolution == false) {
                    Stop = true;
                }
                else {
                    for (int i: G[Sink]) {
                        if (Edges[i].To == Source || Parent[Edges[i].To] != -1) {
                            int flowCurrent = INF;
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Minimize(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
                            }
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Edges[j].Flow += flowCurrent;
                                Edges[j ^ 1].Flow -= flowCurrent;
                            }
                            flowSum += flowCurrent;
                        }
                    }
                }
            } while (Stop == false);
            return flowSum;
        }
};

const long double EPS = 1e-12;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(long double c) {
    vector <pair <int, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        int Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true> (n, 0, n - 1, flowEdges).flowSolve();
}

long double Search() {
    long double le = EPS;
    long double ri = 1000000;
    while (ri - le > EPS) {
        long double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool Directed, typename T>
class flowNetwork {
    private:
        class Edge {
            public:
                int From;
                int To;
                T Capacity;
                T Flow;

                Edge(
                  int __From = 0,
                  int __To = 0,
                  T __Capacity = 0,
                  T __Flow = 0
                ) {
                    From = __From;
                    To = __To;
                    Capacity = __Capacity;
                    Flow = __Flow;
                }
        };

        int Size;
        int Source;
        int Sink;
        int numEdges;
        vector <Edge> Edges;
        vector <vector <int>> G;
        static const T INF = numeric_limits <T> :: max();

        inline void linkNodes(int x, int y, T c) {
            Edges.push_back(Edge(x, y, c, 0));
            G[x].push_back(numEdges);
            numEdges++;

            Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
            G[y].push_back(numEdges);
            numEdges++;
        }

        pair <bool, vector <int>> findPath() {
            vector <int> Parent(Size, -1);
            queue <int> Q;
            for (Q.push(Source); Q.empty() == false; Q.pop()) {
                int x = Q.front();
                if (x != Sink) {
                    for (int i: G[x]) {
                        if (Edges[i].Flow < Edges[i].Capacity) {
                            int y = Edges[i].To;
                            if (y != Source && Parent[y] == -1) {
                                Parent[y] = i;
                                Q.push(y);
                            }
                        }
                    }
                }
            }
            if (Parent[Sink] != -1) return {true, Parent};
            else return {false, vector <int>()};
        }

    public:
        flowNetwork(
          const int __Size,
          const int __Source,
          const int __Sink,
          const vector <pair <T, pair <int, int>>> &Edges
        ) {
            Size = __Size;
            Source = __Source;
            Sink = __Sink;
            numEdges = 0;
            G = vector <vector <int>>(Size, vector <int>());
            for (const pair <T, pair <int, int>> &Edge: Edges) {
                int x;
                int y;
                T c = Edge.fi;
                tie(x, y) = Edge.se;
                linkNodes(x, y, c);
            }
        }

        T flowSolve() {
            T flowSum = 0;
            bool Stop = false;
            do {
                bool foundSolution;
                vector <int> Parent;
                tie(foundSolution, Parent) = findPath();
                if (foundSolution == false) {
                    Stop = true;
                }
                else {
                    for (int i: G[Sink]) {
                        if (Edges[i].To == Source || Parent[Edges[i].To] != -1) {
                            T flowCurrent = INF;
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Minimize(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
                            }
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Edges[j].Flow += flowCurrent;
                                Edges[j ^ 1].Flow -= flowCurrent;
                            }
                            flowSum += flowCurrent;
                        }
                    }
                }
            } while (Stop == false);
            return flowSum;
        }
};

const long double EPS = 1e-12;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(long double c) {
    vector <pair <ll, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        ll Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true, ll> (n, 0, n - 1, flowEdges).flowSolve();
}

long double Search() {
    long double le = EPS;
    long double ri = 1000000;
    while (ri - le > EPS) {
        long double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool Directed>
class flowNetwork {
    private:
        class Edge {
            public:
                int From;
                int To;
                int Capacity;
                int Flow;

                Edge(
                  int __From = 0,
                  int __To = 0,
                  int __Capacity = 0,
                  int __Flow = 0
                ) {
                    From = __From;
                    To = __To;
                    Capacity = __Capacity;
                    Flow = __Flow;
                }
        };

        int Size;
        int Source;
        int Sink;
        int numEdges;
        vector <Edge> Edges;
        vector <vector <int>> G;
        static const int INF = numeric_limits <int> :: max();

        inline void linkNodes(int x, int y, int c) {
            Edges.push_back(Edge(x, y, c, 0));
            G[x].push_back(numEdges);
            numEdges++;

            Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
            G[y].push_back(numEdges);
            numEdges++;
        }

        pair <bool, vector <int>> findPath() {
            vector <int> Parent(Size, -1);
            queue <int> Q;
            for (Q.push(Source); Q.empty() == false; Q.pop()) {
                int x = Q.front();
                if (x != Sink) {
                    for (int i: G[x]) {
                        if (Edges[i].Flow < Edges[i].Capacity) {
                            int y = Edges[i].To;
                            if (y != Source && Parent[y] == -1) {
                                Parent[y] = i;
                                Q.push(y);
                            }
                        }
                    }
                }
            }
            if (Parent[Sink] != -1) return {true, Parent};
            else return {false, vector <int>()};
        }

    public:
        flowNetwork(
          const int __Size,
          const int __Source,
          const int __Sink,
          const vector <pair <int, pair <int, int>>> &Edges
        ) {
            Size = __Size;
            Source = __Source;
            Sink = __Sink;
            numEdges = 0;
            G = vector <vector <int>>(Size, vector <int>());
            for (const pair <int, pair <int, int>> &Edge: Edges) {
                int x;
                int y;
                int c = Edge.fi;
                tie(x, y) = Edge.se;
                linkNodes(x, y, c);
            }
        }

        int flowSolve() {
            int flowSum = 0;
            bool Stop = false;
            do {
                bool foundSolution;
                vector <int> Parent;
                tie(foundSolution, Parent) = findPath();
                if (foundSolution == false) {
                    Stop = true;
                }
                else {
                    for (int i: G[Sink]) {
                        if (Edges[i].To == Source || Parent[Edges[i].To] != -1) {
                            int flowCurrent = INF;
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Minimize(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
                            }
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Edges[j].Flow += flowCurrent;
                                Edges[j ^ 1].Flow -= flowCurrent;
                            }
                            flowSum += flowCurrent;
                        }
                    }
                }
            } while (Stop == false);
            return flowSum;
        }
};

const double EPS = 1e-10;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(double c) {
    vector <pair <int, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        int Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true> (n, 0, n - 1, flowEdges).flowSolve();
}

double Search() {
    double le = 0;
    double ri = 1000000;
    while (ri - le > EPS) {
        double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool Directed>
class flowNetwork {
    private:
        class Edge {
            public:
                int From;
                int To;
                int Capacity;
                int Flow;

                Edge(
                  int __From = 0,
                  int __To = 0,
                  int __Capacity = 0,
                  int __Flow = 0
                ) {
                    From = __From;
                    To = __To;
                    Capacity = __Capacity;
                    Flow = __Flow;
                }
        };

        int Size;
        int Source;
        int Sink;
        int numEdges;
        vector <Edge> Edges;
        vector <vector <int>> G;
        static const int INF = numeric_limits <int> :: max();

        inline void linkNodes(int x, int y, int c) {
            Edges.push_back(Edge(x, y, c, 0));
            G[x].push_back(numEdges);
            numEdges++;

            Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
            G[y].push_back(numEdges);
            numEdges++;
        }

        pair <bool, vector <int>> findPath() {
            vector <int> Parent(Size, -1);
            queue <int> Q;
            for (Q.push(Source); Q.empty() == false; Q.pop()) {
                int x = Q.front();
                if (x != Sink) {
                    for (int i: G[x]) {
                        if (Edges[i].Flow < Edges[i].Capacity) {
                            int y = Edges[i].To;
                            if (y != Source && Parent[y] == -1) {
                                Parent[y] = i;
                                Q.push(y);
                            }
                        }
                    }
                }
            }
            if (Parent[Sink] != -1) return {true, Parent};
            else return {false, vector <int>()};
        }

    public:
        flowNetwork(
          const int __Size,
          const int __Source,
          const int __Sink,
          const vector <pair <int, pair <int, int>>> &Edges
        ) {
            Size = __Size;
            Source = __Source;
            Sink = __Sink;
            numEdges = 0;
            G = vector <vector <int>>(Size, vector <int>());
            for (const pair <int, pair <int, int>> &Edge: Edges) {
                int x;
                int y;
                int c = Edge.fi;
                tie(x, y) = Edge.se;
                linkNodes(x, y, c);
            }
        }

        int flowSolve() {
            int k = 0;
            int flowSum = 0;
            bool Stop = false;
            do {
                k++;
                assert(k < 100);
                bool foundSolution;
                vector <int> Parent;
                tie(foundSolution, Parent) = findPath();
                if (foundSolution == false) {
                    Stop = true;
                }
                else {
                    for (int i: G[Sink]) {
                        if (Edges[i].To == Source || Parent[Edges[i].To] != -1) {
                            int flowCurrent = INF;
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Minimize(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
                            }
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Edges[j].Flow += flowCurrent;
                                Edges[j ^ 1].Flow -= flowCurrent;
                            }
                            flowSum += flowCurrent;
                        }
                    }
                }
            } while (Stop == false);
            return flowSum;
        }
};

const double EPS = 1e-10;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(double c) {
    vector <pair <int, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        int Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true> (n, 0, n - 1, flowEdges).flowSolve();
}

double Search() {
    double le = EPS;
    double ri = 1000000;
    while (ri - le > EPS) {
        double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool Directed>
class flowNetwork {
    private:
        class Edge {
            public:
                int From;
                int To;
                int Capacity;
                int Flow;

                Edge(
                  int __From = 0,
                  int __To = 0,
                  int __Capacity = 0,
                  int __Flow = 0
                ) {
                    From = __From;
                    To = __To;
                    Capacity = __Capacity;
                    Flow = __Flow;
                }
        };

        int Size;
        int Source;
        int Sink;
        int numEdges;
        vector <Edge> Edges;
        vector <vector <int>> G;
        static const int INF = numeric_limits <int> :: max();

        inline void linkNodes(int x, int y, int c) {
            Edges.push_back(Edge(x, y, c, 0));
            G[x].push_back(numEdges);
            numEdges++;

            Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
            G[y].push_back(numEdges);
            numEdges++;
        }

        pair <bool, vector <int>> findPath() {
            vector <int> Parent(Size, -1);
            queue <int> Q;
            for (Q.push(Source); Q.empty() == false; Q.pop()) {
                int x = Q.front();
                if (x != Sink) {
                    for (int i: G[x]) {
                        if (Edges[i].Flow < Edges[i].Capacity) {
                            int y = Edges[i].To;
                            if (y != Source && Parent[y] == -1) {
                                Parent[y] = i;
                                Q.push(y);
                            }
                        }
                    }
                }
            }
            if (Parent[Sink] != -1) return {true, Parent};
            else return {false, vector <int>()};
        }

    public:
        flowNetwork(
          const int __Size,
          const int __Source,
          const int __Sink,
          const vector <pair <int, pair <int, int>>> &Edges
        ) {
            Size = __Size;
            Source = __Source;
            Sink = __Sink;
            numEdges = 0;
            G = vector <vector <int>>(Size, vector <int>());
            for (const pair <int, pair <int, int>> &Edge: Edges) {
                int x;
                int y;
                int c = Edge.fi;
                tie(x, y) = Edge.se;
                linkNodes(x, y, c);
            }
        }

        int flowSolve() {
            int k = 0;
            int flowSum = 0;
            bool Stop = false;
            do {
                bool foundSolution;
                vector <int> Parent;
                tie(foundSolution, Parent) = findPath();
                if (foundSolution == false) {
                    Stop = true;
                }
                else {
                    for (int i: G[Sink]) {
                        if (Edges[i].To == Source || Parent[Edges[i].To] != -1) {
                            int flowCurrent = INF;
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Minimize(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
                            }
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Edges[j].Flow += flowCurrent;
                                Edges[j ^ 1].Flow -= flowCurrent;
                            }
                            flowSum += flowCurrent;
                        }
                    }
                }
            } while (Stop == false);
            return flowSum;
        }
};

const long double EPS = 1e-12;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(long double c) {
    vector <pair <int, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        int Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true> (n, 0, n - 1, flowEdges).flowSolve();
}

long double Search() {
    long double le = 1.0 / k;
    long double ri = 1000000;
    while (ri - le > EPS) {
        long double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool Directed>
class flowNetwork {
    private:
        class Edge {
            public:
                int From;
                int To;
                int Capacity;
                int Flow;

                Edge(
                  int __From = 0,
                  int __To = 0,
                  int __Capacity = 0,
                  int __Flow = 0
                ) {
                    From = __From;
                    To = __To;
                    Capacity = __Capacity;
                    Flow = __Flow;
                }
        };

        int Size;
        int Source;
        int Sink;
        int numEdges;
        vector <Edge> Edges;
        vector <vector <int>> G;
        static const int INF = numeric_limits <int> :: max();

        inline void linkNodes(int x, int y, int c) {
            Edges.push_back(Edge(x, y, c, 0));
            G[x].push_back(numEdges);
            numEdges++;

            Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
            G[y].push_back(numEdges);
            numEdges++;
        }

        pair <bool, vector <int>> findPath() {
            vector <int> Parent(Size, -1);
            queue <int> Q;
            for (Q.push(Source); Q.empty() == false; Q.pop()) {
                int x = Q.front();
                if (x != Sink) {
                    for (int i: G[x]) {
                        if (Edges[i].Flow < Edges[i].Capacity) {
                            int y = Edges[i].To;
                            if (y != Source && Parent[y] == -1) {
                                Parent[y] = i;
                                Q.push(y);
                            }
                        }
                    }
                }
            }
            if (Parent[Sink] != -1) return {true, Parent};
            else return {false, vector <int>()};
        }

    public:
        flowNetwork(
          const int __Size,
          const int __Source,
          const int __Sink,
          const vector <pair <int, pair <int, int>>> &Edges
        ) {
            Size = __Size;
            Source = __Source;
            Sink = __Sink;
            numEdges = 0;
            G = vector <vector <int>>(Size, vector <int>());
            for (const pair <int, pair <int, int>> &Edge: Edges) {
                int x;
                int y;
                int c = Edge.fi;
                tie(x, y) = Edge.se;
                linkNodes(x, y, c);
            }
        }

        int flowSolve() {
            int k = 0;
            int flowSum = 0;
            bool Stop = false;
            do {
                bool foundSolution;
                vector <int> Parent;
                tie(foundSolution, Parent) = findPath();
                if (foundSolution == false) {
                    Stop = true;
                }
                else {
                    for (int i: G[Sink]) {
                        if (Edges[i].To == Source || Parent[Edges[i].To] != -1) {
                            int flowCurrent = INF;
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Minimize(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
                            }
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Edges[j].Flow += flowCurrent;
                                Edges[j ^ 1].Flow -= flowCurrent;
                            }
                            flowSum += flowCurrent;
                        }
                    }
                }
            } while (Stop == false);
            return flowSum;
        }
};

const long double EPS = 1e-10;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(long double c) {
    vector <pair <int, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        int Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true> (n, 0, n - 1, flowEdges).flowSolve();
}

long double Search() {
    long double le = EPS;
    long double ri = 1000000;
    while (ri - le > EPS) {
        long double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool Directed>
class flowNetwork {
    private:
        class Edge {
            public:
                int From;
                int To;
                int Capacity;
                int Flow;

                Edge(
                  int __From = 0,
                  int __To = 0,
                  int __Capacity = 0,
                  int __Flow = 0
                ) {
                    From = __From;
                    To = __To;
                    Capacity = __Capacity;
                    Flow = __Flow;
                }
        };

        int Size;
        int Source;
        int Sink;
        int numEdges;
        vector <Edge> Edges;
        vector <vector <int>> G;
        static const int INF = numeric_limits <int> :: max();

        inline void linkNodes(int x, int y, int c) {
            Edges.push_back(Edge(x, y, c, 0));
            G[x].push_back(numEdges);
            numEdges++;

            Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
            G[y].push_back(numEdges);
            numEdges++;
        }

        pair <bool, vector <int>> findPath() {
            vector <int> Parent(Size, -1);
            queue <int> Q;
            for (Q.push(Source); Q.empty() == false; Q.pop()) {
                int x = Q.front();
                if (x != Sink) {
                    for (int i: G[x]) {
                        if (Edges[i].Flow < Edges[i].Capacity) {
                            int y = Edges[i].To;
                            if (y != Source && Parent[y] == -1) {
                                Parent[y] = i;
                                Q.push(y);
                            }
                        }
                    }
                }
            }
            if (Parent[Sink] != -1) return {true, Parent};
            else return {false, vector <int>()};
        }

    public:
        flowNetwork(
          const int __Size,
          const int __Source,
          const int __Sink,
          const vector <pair <int, pair <int, int>>> &Edges
        ) {
            Size = __Size;
            Source = __Source;
            Sink = __Sink;
            numEdges = 0;
            G = vector <vector <int>>(Size, vector <int>());
            for (const pair <int, pair <int, int>> &Edge: Edges) {
                int x;
                int y;
                int c = Edge.fi;
                tie(x, y) = Edge.se;
                linkNodes(x, y, c);
            }
        }

        int flowSolve() {
            int k = 0;
            int flowSum = 0;
            bool Stop = false;
            do {
                bool foundSolution;
                vector <int> Parent;
                tie(foundSolution, Parent) = findPath();
                if (foundSolution == false) {
                    Stop = true;
                }
                else {
                    for (int i: G[Sink]) {
                        if (Edges[i].To == Source || Parent[Edges[i].To] != -1) {
                            int flowCurrent = INF;
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Minimize(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
                            }
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Edges[j].Flow += flowCurrent;
                                Edges[j ^ 1].Flow -= flowCurrent;
                            }
                            flowSum += flowCurrent;
                        }
                    }
                }
            } while (Stop == false);
            return flowSum;
        }
};

const long double EPS = 1e-12;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(long double c) {
    vector <pair <int, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        int Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true> (n, 0, n - 1, flowEdges).flowSolve();
}

long double Search() {
    long double le = 1.0 / k;
    long double ri = 1000000;
    while (le < ri) {
        long double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool isDirected, typename capType>
class flowNetwork {
    private:
        class Edge {
            public:
                int to;
                capType c;
                capType f;

                Edge(
                  int __to = 0,
                  capType __c = 0,
                  capType __f = 0
                ) {
                    to = __to;
                    c = __c;
                    f = __f;
                }
        };

        static const capType Inf = numeric_limits <capType> :: max();
        int n;
        int m;
        int s;
        int t;
        vector <int> p;
        vector <int> d;
        vector <Edge> e;
        vector <vector <int>> g;

        inline void link(int x, int y, capType c) {
            for (int i = 0; i < 2; i++) {
                e.push_back(Edge(y, c, 0));
                g[x].push_back(m++);
                c *= (isDirected == false);
                swap(x, y);
            }
        }

        inline bool bfs() {
            d = vector <int>(n, -1);
            queue <int> q;
            d[s] = 0;
            for (q.push(s); q.empty() == false; q.pop()) {
                int x = q.front();
                for (int i: g[x]) {
                    if (e[i].f < e[i].c) {
                        int y = e[i].to;
                        if (d[y] == -1) {
                            d[y] = d[x] + 1;
                            q.push(y);
                        }
                    }
                }
            }
            return (d[t] != -1);
        }

        capType dfs(int x, capType f) {
            if (x == t) {
                return f;
            }
            else {
                if (f == 0) {
                    return f;
                }
                else {
                    while (p[x] < g[x].size()) {
                        int i = g[x][p[x]];
                        int y = e[i].to;
                        if (d[y] == d[x] + 1) {
                            capType fn = dfs(y, min(f, e[i].c - e[i].f));
                            if (fn > 0) {
                                e[i].f += fn;
                                e[i ^ 1].f -= fn;
                                return fn;
                            }
                        }
                        p[x]++;
                    }
                    return 0;
                }
            }
        }

    public:
        flowNetwork(
          int __n,
          int __s,
          int __t,
          const vector <pair <capType, pair <int, int>>> &edges
        ) {
            m = 0;
            n = __n;
            s = __s;
            t = __t;
            g = vector <vector <int>>(n, vector <int>());
            for (const auto &edge: edges) {
                link(edge.se.fi, edge.se.se, edge.fi);
            }
        }

        capType solve() {
            capType f = 0;
            bool done = false;
            do {
                if (bfs() == false) {
                    done = true;
                }
                else {
                    p = vector <int>(n, 0);
                    capType fn;
                    do {
                        fn = dfs(s, Inf);
                        f += fn;
                    } while (fn != 0);
                }
            } while (done == false);
            return f;
        }
};

const long double EPS = 1e-12;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(long double c) {
    vector <pair <ll, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        ll Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true, ll> (n, 0, n - 1, flowEdges).solve();
}

long double Search() {
    long double le = EPS;
    long double ri = 1000000;
    while (ri - le > EPS) {
        long double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

/** <-----------------------------------Debug-----------------------------------------> */

#define failDump() cerr << "Failed here?" << "\n"
#define varDump(x) cerr << (#x) << ": " << (x) << '\n'
#define arrDump(x, l, r) do{ cerr << #x"[]: "; for(int __i__ = l; __i__ <= r; __i__++) cerr << x[__i__] << " "; cerr << '\n' ;} while(0)

/** <----------------------------------Helper-----------------------------------------> */

typedef long long ll;

#define fi first
#define se second

/** <---------------------------------------------------------------------------------> */

template <typename T, typename U> void Maximize(T &x, U y) {
    if (x < y) {
        x = y;
    }
}

template <typename T, typename U> void Minimize(T &x, U y) {
    if (x > y) {
        x = y;
    }
}

template <typename T> int Sign(const T &x) {
    return (x < 0 ? -1 : (x == 0 ? 0 : +1));
}

/** <-----------------------------Code Starts Here------------------------------------> */

template <bool Directed>
class flowNetwork {
    private:
        class Edge {
            public:
                int From;
                int To;
                int Capacity;
                int Flow;

                Edge(
                  int __From = 0,
                  int __To = 0,
                  int __Capacity = 0,
                  int __Flow = 0
                ) {
                    From = __From;
                    To = __To;
                    Capacity = __Capacity;
                    Flow = __Flow;
                }
        };

        int Size;
        int Source;
        int Sink;
        int numEdges;
        vector <Edge> Edges;
        vector <vector <int>> G;
        static const int INF = numeric_limits <int> :: max();

        inline void linkNodes(int x, int y, int c) {
            Edges.push_back(Edge(x, y, c, 0));
            G[x].push_back(numEdges);
            numEdges++;

            Edges.push_back(Edge(y, x, (Directed == true ? 0 : c), 0));
            G[y].push_back(numEdges);
            numEdges++;
        }

        pair <bool, vector <int>> findPath() {
            vector <int> Parent(Size, -1);
            queue <int> Q;
            for (Q.push(Source); Q.empty() == false; Q.pop()) {
                int x = Q.front();
                if (x != Sink) {
                    for (int i: G[x]) {
                        if (Edges[i].Flow < Edges[i].Capacity) {
                            int y = Edges[i].To;
                            if (y != Source && Parent[y] == -1) {
                                Parent[y] = i;
                                Q.push(y);
                            }
                        }
                    }
                }
            }
            if (Parent[Sink] != -1) return {true, Parent};
            else return {false, vector <int>()};
        }

    public:
        flowNetwork(
          const int __Size,
          const int __Source,
          const int __Sink,
          const vector <pair <int, pair <int, int>>> &Edges
        ) {
            Size = __Size;
            Source = __Source;
            Sink = __Sink;
            numEdges = 0;
            G = vector <vector <int>>(Size, vector <int>());
            for (const pair <int, pair <int, int>> &Edge: Edges) {
                int x;
                int y;
                int c = Edge.fi;
                tie(x, y) = Edge.se;
                linkNodes(x, y, c);
            }
        }

        int flowSolve() {
            int k = 0;
            int flowSum = 0;
            bool Stop = false;
            do {
                bool foundSolution;
                vector <int> Parent;
                tie(foundSolution, Parent) = findPath();
                if (foundSolution == false) {
                    Stop = true;
                }
                else {
                    for (int i: G[Sink]) {
                        if (Edges[i].To == Source || Parent[Edges[i].To] != -1) {
                            int flowCurrent = INF;
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Minimize(flowCurrent, Edges[j].Capacity - Edges[j].Flow);
                            }
                            for (int j = i ^ 1; j != -1; j = Parent[Edges[j].From]) {
                                Edges[j].Flow += flowCurrent;
                                Edges[j ^ 1].Flow -= flowCurrent;
                            }
                            flowSum += flowCurrent;
                        }
                    }
                }
            } while (Stop == false);
            return flowSum;
        }
};

const double EPS = 1e-7;

int n;
int m;
int k;
vector <pair <int, pair <int, int>>> Edges;

int findFlow(double c) {
    vector <pair <int, pair <int, int>>> flowEdges;
    for (int i = 0; i < m; i++) {
        int Cost = floor(Edges[i].fi / c);
        flowEdges.push_back({Cost, Edges[i].se});
    }
    return flowNetwork <true> (n, 0, n - 1, flowEdges).flowSolve();
}

double Search() {
    double le = EPS;
    double ri = 1000000;
    while (ri - le > EPS) {
        double mi = (le + ri) / 2;
        if (findFlow(mi) < k) ri = mi;
        else le = mi;
    }
    return le;
}

int main() {
    #ifndef ONLINE_JUDGE
        ifstream cin("file.in");
        ofstream cout("file.out");
    #endif // ONLINE_JUDGE
    cin.tie(nullptr);
    ios_base :: sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        x--;
        y--;
        Edges.push_back({c, {x, y}});
    }

    cout << setprecision(10) << fixed;
    cout << Search() * k << "\n";
    return 0;
}


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

#define sz(v)               ((int)v.size())
#define ll                  long long
#define all(v)              (v.begin()) , (v.end())
#define rall(v)             (v.rbegin()) , (v.rend())

struct edge{
    int to, cap, flow, rev;
    edge(int _to, int _cap, int _flow, int _rev){
        to = _to, cap = _cap, flow = _flow, rev = _rev;
    }
};

struct Dinic{
    vector <edge> adj[105];
    int level[105], start[105], color[105];
    int sink, src;

    Dinic(int s, int t){
        src = s;
        sink = t;
        memset(start, 0, sizeof(start));
        memset(color, -1, sizeof color);
    }

    void addEdge(int from, int to, int cap1, int cap2)
    {
        // from -> to has cap1
        // to -> from has cap2
        edge e1 = edge(to, cap1, 0, adj[to].size() );
        edge e2 = edge(from, cap2, 0, adj[from].size() );

        adj[from].push_back(e1);
        adj[to].push_back(e2);
    }
    bool bfs()
    {
        memset(level, -1, sizeof(level));
        level[src] = 0;
        queue <int> q;
        q.push(src);

        while(!q.empty()){
            int cur = q.front();
            q.pop();

            for(edge &e : adj[cur]){
                if(level[e.to] == -1 && e.flow < e.cap){
                    level[e.to] = level[cur] + 1;
                    q.push(e.to);
                }
            }
        }
        return level[sink] != -1;
    }

    int sendFlow(int u, int flow)
    {
        if(u == sink)
            return flow;

        for( ;start[u] < sz(adj[u]);start[u]++){
            edge &e = adj[u][start[u]];

            if(level[e.to] == level[u] + 1 && e.flow < e.cap){
                int curflow = min(flow, e.cap - e.flow);

                curflow = sendFlow(e.to, curflow);

                if(curflow > 0){
                    e.flow += curflow;
                    adj[e.to][e.rev].flow -= curflow;
                    return curflow;
                }
            }
        }
        return 0;
    }

    int maxFlow()
    {
        if(src == sink)
            return 0;

        int totalflow = 0;

        while(bfs()){
            memset(start, 0, sizeof(start));
            int flow;
            while( (flow = sendFlow(src, INT_MAX)))
                totalflow += flow;
        }
        return totalflow;
    }

    void dfs(int node)
    {
        color[node] = 1;
        for(edge &e : adj[node])
            if(e.flow < e.cap && color[e.to] == -1)
                dfs(e.to);
    }

};

const double eps = 1e-8;

int n, m, x;
int u[505], v[505], c[505];
vector <int> minCuts;

bool valid(double a)
{
    int cnt = 0;
    for(int i = 0; i < sz(minCuts); i++){
        int t = 1.0 * minCuts[i] / a;
        cnt += t;
    }
    return cnt >= x;
}
int main ()
{
    //freopen("input.txt", "r", stdin);
    scanf("%d%d%d", &n, &m, &x);
    Dinic dinic(1, n);
    for(int i = 0; i < m; i++){
        scanf("%d%d%d", u + i, v + i, c + i);
        dinic.addEdge(u[i], v[i], c[i], 0);
    }
    dinic.maxFlow();
    dinic.dfs(1);

    for(int i = 0; i < m; i++){
        if(dinic.color[u[i]] * dinic.color[v[i]] == -1){
            minCuts.push_back(c[i]);
            //printf("%d %d\n", u[i], v[i]);
        }
    }

    double L = 0, R = 1e10;

    for(int i = 0; i < 300; i++){
        double mid = (L + R) / 2;
        if(valid(mid))
            L = mid;
        else
            R = mid;
    }
    printf("%.10lf\n", x * L);
    return 0;
}


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

#define sz(v)               ((int)v.size())
#define ll                  long long
#define all(v)              (v.begin()) , (v.end())
#define rall(v)             (v.rbegin()) , (v.rend())

struct edge{
    int to, cap, flow, rev;
    edge(int _to, int _cap, int _flow, int _rev){
        to = _to, cap = _cap, flow = _flow, rev = _rev;
    }
};

struct Dinic{
    vector <edge> adj[105];
    int level[105], start[105], color[105];
    int sink, src;

    Dinic(int s, int t){
        src = s;
        sink = t;
        memset(start, 0, sizeof(start));
    }

    void addEdge(int from, int to, int cap1, int cap2)
    {
        // from -> to has cap1
        // to -> from has cap2
        edge e1 = edge(to, cap1, 0, adj[to].size() );
        edge e2 = edge(from, cap2, 0, adj[from].size() );

        adj[from].push_back(e1);
        adj[to].push_back(e2);
    }
    bool bfs()
    {
        memset(level, -1, sizeof(level));
        level[src] = 0;
        queue <int> q;
        q.push(src);

        while(!q.empty()){
            int cur = q.front();
            q.pop();

            for(edge &e : adj[cur]){
                if(level[e.to] == -1 && e.flow < e.cap){
                    level[e.to] = level[cur] + 1;
                    q.push(e.to);
                }
            }
        }
        return level[sink] != -1;
    }

    int sendFlow(int u, int flow)
    {
        if(u == sink)
            return flow;

        for( ;start[u] < sz(adj[u]);start[u]++){
            edge &e = adj[u][start[u]];

            if(level[e.to] == level[u] + 1 && e.flow < e.cap){
                int curflow = min(flow, e.cap - e.flow);

                curflow = sendFlow(e.to, curflow);

                if(curflow > 0){
                    e.flow += curflow;
                    adj[e.to][e.rev].flow -= curflow;
                    return curflow;
                }
            }
        }
        return 0;
    }

    int maxFlow()
    {
        if(src == sink)
            return 0;

        int totalflow = 0;

        while(bfs()){
            memset(start, 0, sizeof(start));
            int flow;
            while( (flow = sendFlow(src, INT_MAX)))
                totalflow += flow;
        }
        return totalflow;
    }
};

const double eps = 1e-8;

int n, m, x;
int u[505], v[505], c[505];

bool valid(long double a)
{
    Dinic dinic(1, n);
    for(int i = 0; i < m; i++){
        long long w = 1LL * c[i] / a;
        w = min(w, 1LL * INT_MAX);
        dinic.addEdge(u[i], v[i], w, 0);
    }
    return dinic.maxFlow() >= x;
}
int main ()
{
    //freopen("input.txt", "r", stdin);
    scanf("%d%d%d", &n, &m, &x);
    Dinic dinic(1, n);
    for(int i = 0; i < m; i++)
        scanf("%d%d%d", u + i, v + i, c + i);

    double L = 0, R = 1e10;

    for(int i = 0; i < 300; i++){
        double mid = (L + R) / 2;
        if(valid(mid))
            L = mid;
        else
            R = mid;
    }
    printf("%.10f\n", x * L);
    return 0;
}