#include <iostream>
#include <queue>
#include <vector>
#include <stdio.h>
using namespace std;
typedef long double ld;
typedef vector<ld> vld;
typedef vector<vld> vvld;
vvld c,f;
int n,u[101],counter,p[101];
bool check(ld x, int k){
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			f[i][j]=0;
	p[1]=-1;
	while(k--){
		counter++;
		queue<int> q;
		q.push(1);
		u[1] = counter;
		while(!q.empty()){
			int v = q.front();
			q.pop();
			for(int i=1;i<=n;i++){
				if(u[i] != counter && c[v][i] - f[v][i] >= x){
					p[i] = v;
					u[i] = counter;
					q.push(i);
				}
			}
		}
		if(u[n] != counter)return false;
		for(int cur = n;cur != 1;cur = p[cur]){
			int prev = p[cur];
			f[prev][cur] += x;
			f[cur][prev] -= x;
		}
	}
	return true;
}
int main(){
	int m,a,b,k;
	ld cost,l=0.0,r=0.0;
	cin>>n>>m>>k;
	f.assign(n+1,vld(n+1,0.0));
	c.assign(n+1,vld(n+1,0.0));
	for(int i=0;i<m;i++){
		cin>>a>>b>>cost;
		c[a][b] = cost;
		r=max(r,cost);
	}
	while(r-l > 0.00000001){
		ld m = (r+l)/2.0;
		if(check(m,k)){
			l = m;
		}
		else{
			r = m;
		}
	}
	ld ans = (l+r)/2.0*k;
	printf("%.6f\n",ans);
}


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <vector>
#include <set>
#include <string.h>
#include <iostream>
#include<string>
#include <algorithm>
#include <map>
#include <queue>

using namespace std;

struct edge
{
	int u;
	int v;
	int c;
	int fl;
	edge(){}
	edge(int u1, int v1, int c1, int fl1){
		u = u1;
		v = v1;
		c = c1;
		fl = fl1;
	}
};
int x;

const int maxN = 300;
bool used[maxN];
const int lg = 20;

vector <vector <int> > ls;
vector <edge> ed;

void add_edge(int u, int v, int c)
{
	edge e1 = edge(u, v, c, 0);
	edge e2 = edge(v, u, 0, 0);
	ls[u].push_back((int)ed.size());
	ed.push_back(e1);
	ls[v].push_back((int)ed.size());
	ed.push_back(e2);
}

int n, m;

int P[maxN];

bool bfs(int p)
{
	int flow = (1 << p);
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
	}
	for (int i = 1; i <= n; i++)
	{
		P[i] = -1;
	}

	queue <int> q;
	q.push(1);
	used[1] = true;

	while (!q.empty())
	{
		int v = q.front(); q.pop();
		for (int i = 0; i < (int)ls[v].size(); i++)
		{
			edge to = ed[ls[v][i]];
			if (to.fl + flow <= to.c && !used[to.v])
			{
				used[to.v] = true;
				P[to.v] = ls[v][i];
				q.push(to.v);
			}
		}
	}

	if (!used[n])
	{
		return false;
	}
	int cur = n;
	while (cur > 1)
	{
		int num = P[cur];
		ed[num].fl += flow;
		ed[num ^ 1].fl -= flow;
		cur = ed[num].u;
	}
	return true;

}

vector <pair <int, pair <int, int> > > ee;

int main()
{
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> x;
	for (int i = 1; i <= m; i++){
		int x, y, z;
		cin >> x >> y >> z;
		ee.push_back(make_pair(x, make_pair(y, z)));
	}
	int k = m;
	long double l = 0;
	long double r = 1000001;

	for (int t = 1; t <= 100; t++){
		ls.clear();
		ed.clear();
		ls.resize(n + 1);
		for (int i = 1; i <= n; i++){
			used[i] = false;
			P[i] = -1;
		}
		long double m = (l + r) / 2;
		long long ans = 0;
		for (int i = 1; i <= k; i++){
			int x, y, z;
			x = ee[i - 1].first;
			y = ee[i - 1].second.first;
			z = ee[i - 1].second.second;
			long double tmp = z * 1.0 / m;
			tmp = min(tmp, (long double)100010);
			int pp = tmp;
			add_edge(x, y, pp);
		}
		bool f = false;
		for (int i = 19; i >= 0; i--)
		{
			if (f)break;
			while (bfs(i))
			{
				ans += (1ll << i);
				if (ans >= x){
					f = true;
					break;
				}
			}
		}
		if (f){
			l = m;
		}
		else{
			r = m;
		}
	}

	printf("%.10lf\n", (double)(l * x));
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <vector>
#include <set>
#include <string.h>
#include <iostream>
#include<string>
#include <algorithm>
#include <map>
#include <queue>

using namespace std;

struct edge
{
	int u;
	int v;
	int c;
	int fl;
};
int x;

const int maxN = 300;
bool used[maxN];
const int lg = 20;

vector <vector <int> > ls;
vector <edge> ed;

void add_edge(int u, int v, int c)
{
	edge e1 = edge{ u, v, c, 0 };
	edge e2 = edge{ v, u, 0, 0 };
	ls[u].push_back((int)ed.size());
	ed.push_back(e1);
	ls[v].push_back((int)ed.size());
	ed.push_back(e2);
}

int n, m;

int P[maxN];

bool bfs(int p)
{
	int flow = (1 << p);
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
	}
	for (int i = 1; i <= n; i++)
	{
		P[i] = -1;
	}

	queue <int> q;
	q.push(1);
	used[1] = true;

	while (!q.empty())
	{
		int v = q.front(); q.pop();
		for (int i = 0; i < (int)ls[v].size(); i++)
		{
			edge to = ed[ls[v][i]];
			if (to.fl + flow <= to.c && !used[to.v])
			{
				used[to.v] = true;
				P[to.v] = ls[v][i];
				q.push(to.v);
			}
		}
	}

	if (!used[n])
	{
		return false;
	}
	int cur = n;
	while (cur > 1)
	{
		int num = P[cur];
		ed[num].fl += flow;
		ed[num ^ 1].fl -= flow;
		cur = ed[num].u;
	}
	return true;

}

vector <pair <int, pair <int, int> > > ee;

int main()
{
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> x;
	for (int i = 1; i <= m; i++){
		int x, y, z;
		cin >> x >> y >> z;
		ee.push_back(make_pair(x, make_pair(y, z)));
	}
	int k = m;
	long double l = 0;
	long double r = 1000001;

	for (int t = 1; t <= 100; t++){
		ls.clear();
		ed.clear();
		ls.resize(n + 1);
		for (int i = 1; i <= n; i++){
			used[i] = false;
			P[i] = -1;
		}
		long double m = (l + r) / 2;
		long long ans = 0;
		for (int i = 1; i <= k; i++){
			int x, y, z;
			x = ee[i - 1].first;
			y = ee[i - 1].second.first;
			z = ee[i - 1].second.second;
			long double tmp = z * 1.0 / m;
			tmp = min(tmp, (long double)100000);
			int pp = tmp;
			add_edge(x, y, pp);
		}
		bool f = false;
		for (int i = 19; i >= 0; i--)
		{
			if (f)break;
			while (bfs(i))
			{
				ans += (1ll << i);
				if (ans >= x){
					f = true;
					break;
				}
			}
		}
		if (f){
			l = m;
		}
		else{
			r = m;
		}
	}

	printf("%.10lf\n", (double)(l * x));
	return 0;
}


#include <stdio.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

class dinic{
public:
	struct edge{
		int a,b;
		long long c,f;
	};
	int n,m;
	static const int inf=2000000200;
	vector<edge> list;
	vector<vector<edge*> > adj;
	vector<int> dist;
	vector<int> B;
	int bfs;
	int source,sink;

	void init(int N,int so,int si){
		dist.resize(N+3);
		adj.resize(N+3);
		B.resize(N+3);
		source=so;
		sink=si;
		n=N;
		m=0;
	}
	void add_edge(int from,int to, long long cap,bool directed){
		edge t;
		list.push_back(t);
		list[m].a=from;
		list[m].b=to;
		if(directed){
			list[m].c=cap;
			list[m].f=0;
		} else {
			list[m].c=2*cap;
			list[m].f=cap;
		}
		m++;

	}

	void BFS(){
		B[0]=sink;
		bfs=1;
		for(int i=1;i<=n;i++){
			dist[i]=inf;
		}
		dist[sink]=0;
		int nd,nd_adj;
		for(int i=0;i<bfs;i++){
			nd=B[i];
			for(int i=0;i<adj[nd].size();i++){
				if(adj[nd][i]->a==nd){
					nd_adj=adj[nd][i]->b;
					if(dist[nd_adj]==inf &&  adj[nd][i]->f>0){
						B[bfs++]=nd_adj;
						dist[nd_adj]=dist[nd]+1;
					}
				} else {
					nd_adj=adj[nd][i]->a;
					if(dist[nd_adj]==inf && adj[nd][i]->f<adj[nd][i]->c){
						B[bfs++]=nd_adj;
						dist[nd_adj]=dist[nd]+1;
					}
				}
			}
		}
	}
	long long dfs(int node,long long flow){
		long long ret=0;
		if(node==sink){
			return flow;
		}
		for(int i=0;i<adj[node].size();i++){
			if(flow==0)break;
			if(adj[node][i]->a==node){
				int nd_adj=adj[node][i]->b;
				if(dist[node]==dist[nd_adj]+1 && adj[node][i]->f<adj[node][i]->c){
					long long f=dfs(nd_adj,min(flow,0ll+adj[node][i]->c-adj[node][i]->f));
					ret+=f;
					adj[node][i]->f+=f;
					flow-=f;
				}
			} else {
				int nd_adj=adj[node][i]->a;
				if(dist[node]==dist[nd_adj]+1 && adj[node][i]->f>0){
					long long f=dfs(nd_adj,min(flow,0ll+adj[node][i]->f));
					ret+=f;
					adj[node][i]->f-=f;
					flow-=f;
				}
			}
		}
		return ret;
	}
	long long solve(){
		for(int i=0;i<m;i++){
			adj[list[i].a].push_back(&list[i]);
			adj[list[i].b].push_back(&list[i]);
		}
		long long sol=0;
		while(true){
			BFS();
			if(dist[source]==inf)break;
			sol+=dfs(source,10000000000000000ll);
		}
		return sol;
	}
};
int n,m,x;
int from[505];
int to[505];
int cap[505];

bool check(long double qu){
	dinic flow;
	flow.init(n+3,1,n);
	for(int i=0;i<m;i++){
		flow.add_edge(from[i],to[i],(long long)(cap[i]/qu),true);
	}
	return flow.solve()>=x;
}
int main(){
	scanf("%d %d %d",&n,&m,&x);
	//flow.init(n,1,n);
	for(int i=0;i<m;i++){
		scanf("%d %d %d",&from[i],&to[i],&cap[i]);
	}
	long double l=0,r=1000100;
	for(int i=0;i<60;i++){
		long double mid=(r+l)/2;
		if(check(mid)){
			l=mid;
		} else {
			r=mid;
		}
	}
	cout<<fixed;
	cout.precision(11);
	cout<<l*x<<endl;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	long double tl = 0, tr = 1000000.0;
	while (abs(tl - tr) / x > 1e-7){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second/ tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
	long double ftl = tl;
	tl = 0, tr = 1000000.0;
	while (abs(tl - tr)/x > 1e-7){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15lf", (ftl + tl) / 2.0 * x);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	LL a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<LL> g[MAXN];

void add_edge(LL a, LL b, LL cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((LL)e.size());
	e.push_back(e1);
	g[b].push_back((LL)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		LL v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			LL id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

LL dfs(LL v, LL flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
LL dinic() {
	LL flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (LL pushed = dfs(s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	double tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-8){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				LL cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
double ftl = tl;
	tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-8){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				LL cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15f", (tr));
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	long double tl = 0, tr = 1000000.0;
	while (abs(tl - tr) > 1e-15){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i].size() / tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
	long double ftl = tl;
	tl = 0, tr = 1000000.0;
	while (abs(tl - tr) > 1e-15){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i].size() / tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15lf", (ftl + tl) / 2.0 * x);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	long double tl = 0, tr = 1000000.0;
	while (abs(tl - tr) > 1e-8){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second/ tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
	long double ftl = tl;
	tl = 0, tr = 1000000.0;
	while (abs(tl - tr) > 1e-8){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15lf", (ftl + tl) / 2.0 * x);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	double tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-9){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
double ftl = tl;
	tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-9){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15f", (tr));
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs(s, MOD))
			flow += pushed;
	}
	return flow;
}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	long double tl = 0, tr = 1000000.0;
	while (abs(tl - tr) *x> 1e-8){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
	long double ftl = tl;
	tl = 0, tr = 1000000.0;
	while (abs(tl - tr)*x > 1e-8){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15lf", (ftl + tl) / 2.0 * x);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	long double tl = 0, tr = 1000000.0;
	while (abs(tl - tr) / x / max((long double)1.0, abs(tl - tr) / x) > 1e-9){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second/ tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
	long double ftl = tl;
	tl = 0, tr = 1000000.0;
	while (abs(tl - tr) / x / max((long double)1.0, abs(tl - tr) / x) > 1e-9){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15lf", (ftl + tl) / 2.0 * x);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	double tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-7){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
double ftl = tl;
	tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-7){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15f", (tr));
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	long double tl = 0, tr = 1000000.0;
	while (abs(tl - tr) / x > 1e-9){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second/ tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
	long double ftl = tl;
	tl = 0, tr = 1000000.0;
	while (abs(tl - tr)/x > 1e-9){
		long double tm = ((tl + tr) / 2.0);

		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / tm);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15lf", (ftl + tl) / 2.0 * x);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	LL a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<LL> g[MAXN];

void add_edge(LL a, LL b, LL cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((LL)e.size());
	e.push_back(e1);
	g[b].push_back((LL)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		LL v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			LL id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

LL dfs(LL v, LL flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
LL dinic() {
	LL flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (LL pushed = dfs(s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	double tl = 0, tr = 1e6;
	while (abs(tl - tr) * x > 1e-8){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				LL cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
double ftl = tl;
	tl = 0, tr = 1e6;
	while (abs(tl - tr) * x > 1e-8){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				LL cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15f", (tr)* x);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	double tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-8){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
double ftl = tl;
	tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-8){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15f", (tr));
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <map>
#include <string>
#include <iomanip>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <functional>
#include <bitset>
#pragma comment (linker, "/STACK:167177216")
using namespace std;
#define mems(A, val) memset(A, val, sizeof(A))
#define mp(a, b) make_pair(a, b)
#define all(B) (B).begin(), (B).end()
#define forn(it, from, to) for(int it = from; it < to; ++it)
#define forit (it, coll) for(auto it = coll.begin(); it != coll.end(); ++it)
const int MAX = 2147483647;
const int MAXN = 55;
typedef long long LL;
const LL MOD = 1000000000 + 7;
#define M_PI       3.14159265358979323846
struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge(int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back((int)e.size());
	e.push_back(e1);
	g[b].push_back((int)e.size());
	e.push_back(e2);
}

bool bfs() {
	int qh = 0, qt = 0;
	q[qt++] = s;
	memset(d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i = 0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs(int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id ^ 1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}
int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset(ptr, 0, n * sizeof ptr[0]);
		while (int pushed = dfs (s, MOD))
			flow += pushed;
	}
	return flow;
	}
int main(int argc, char* argv[]) {

#ifdef _DEBUG
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	//freopen("numbers.in", "r", stdin); freopen("numbers.out", "w", stdout);
#endif
	int m, x;
	scanf("%d%d%d", &n, &m, &x);
	s = 0, t = n - 1;
	vector<vector<pair<int, int> > > G(n);

	forn(i, 0, m){
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		a--;
		b--;
		G[a].push_back(mp(b, c));
	}

	double tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-9){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow >= x){
			tl = tm;
		}
		else{
			tr = tm;
		}
	}
double ftl = tl;
	tl = 0, tr = 1e18;
	while (abs(tl - tr)  > 1e-9){
		double tm = ((tl + tr) / 2.0);
		double perBear = tm / x;
		for (int i = 0; i < MAXN; ++i){
			g[i].clear();
		}

		e.clear();

		for (int i = 0; i < G.size(); ++i){
			for (int j = 0; j < G[i].size(); ++j){
				int cap = floor(G[i][j].second / perBear);

				add_edge(i, G[i][j].first, cap);
			}
		}

		int flow = dinic();
		if (flow < x){
			tr = tm;
		}
		else{
			tl = tm;
		}
	}

	printf("%.15f", (ftl + tl) / 2.0 * x);
	return 0;
}


#include <stdio.h>
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
#define ll long long int
#define mp make_pair
#define lli %I64d
ll mod = 1e9;
ll inf = 4 * 1e18;

vector<vector<int>> g,back;
vector<vector<double>> c,tek;
int n,x,d[1110],cur[1110];

bool bfs(int s,int f, double m) {
	queue<int> q;
	memset(d,-1,1110);
	d[s]=0;
	q.push(s);
	while(q.size()>0) {
		int v=q.front();
		for(int i=0;i<g[v].size();i++) {
			int to=g[v][i];
			if(d[to]==-1&&tek[v][i]>=m) {
				d[to]=d[v]+1;
				q.push(to);
				if(d[f]!=-1) return true;
			}
		}
		q.pop();
	}
	return false;
}

double dfs(int v,int f,double flow=mod) {
	if(v==f) return flow;
	if(flow<=0) return 0;
	for(;cur[v]<g[v].size();cur[v]++) {
		int to=g[v][cur[v]];
		if(d[to]==d[v]+1&&tek[v][cur[v]]>=flow) {
			double flownew=dfs(to,f,min(c[v][cur[v]],flow));
			if(flownew>0) {
				tek[v][cur[v]]-=flownew;
				tek[to][back[v][cur[v]]]+=flownew;
				return flownew;
			}
		}
	}
	return 0;
}

bool check(double m) {
	int kolmax=0;
	tek=c;
	while(bfs(0,n-1,m)) {
		memset(cur,0,1110);
		bool y=true;
		while(y) {
			double t=dfs(0,n-1,m);
			if(t!=m) y=false;
			else kolmax++;
			if(kolmax>=x) return true;
		}
	}
	return false;
}

int main() {
#pragma warning(disable: 4996)
#pragma comment(linker, "/STACK:268435456")
#ifdef _DEBUG
	freopen("input.txt","rt",stdin);
	freopen("output.txt","wt",stdout);
#endif
	//#ifndef _DEBUG
	//  freopen("partit.in","rt",stdin);
	//  freopen("partit.out","wt",stdout);
	//#endif
	int k,i,j;

	scanf("%d%d%d",&n,&k,&x);
	g.resize(n);
	back.resize(n);
	c.resize(n);
	for(i=0;i<k;i++) {
		int a,b;
		double f;
		scanf("%d%d%lf",&a,&b,&f);
		g[a-1].push_back(b-1);
		g[b-1].push_back(a-1);
		c[a-1].push_back(f);
		c[b-1].push_back(-f);
		back[a-1].push_back(g[b-1].size()-1);
		back[b-1].push_back(g[a-1].size()-1);
	}

	double l=0.0,r=1000000.0;
	while(l<r-1e-11) {
		double m=(l+r)/2;
		if(check(m)) l=m;
		else r=m;
	}

	printf("%.8lf",(double)x*l);

	return 0;
}


#include <stdio.h>
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
#define ll long long int
#define mp make_pair
#define lli %I64d
ll mod = 1e9;
ll inf = 4 * 1e18;

vector<vector<int>> g,back;
vector<vector<double>> c,tek;
int n,x,d[1110],cur[1110];

bool bfs(int s,int f, double m) {
	queue<int> q;
	memset(d,-1,1110);
	d[s]=0;
	q.push(s);
	while(q.size()>0) {
		int v=q.front();
		for(int i=0;i<g[v].size();i++) {
			int to=g[v][i];
			if(d[to]==-1&&tek[v][i]>=m) {
				d[to]=d[v]+1;
				q.push(to);
				if(d[f]!=-1) return true;
			}
		}
		q.pop();
	}
	return false;
}

double dfs(int v,int f,double flow=mod) {
	if(v==f) return flow;
	if(flow<=0) return 0;
	for(;cur[v]<g[v].size();cur[v]++) {
		int to=g[v][cur[v]];
		if(d[to]==d[v]+1&&tek[v][cur[v]]>=flow) {
			double flownew=dfs(to,f,min(c[v][cur[v]],flow));
			if(flownew>0) {
				tek[v][cur[v]]-=flownew;
				tek[to][back[v][cur[v]]]+=flownew;
				return flownew;
			}
		}
	}
	return 0;
}

bool check(double m) {
	int kolmax=0;
	tek=c;
	while(bfs(0,n-1,m)) {
		memset(cur,0,1110);
		bool y=true;
		while(y) {
			double t=dfs(0,n-1,m);
			if(t!=m) y=false;
			else kolmax++;
			if(kolmax>=x) return true;
		}
	}
	return false;
}

int main() {
#pragma warning(disable: 4996)
#pragma comment(linker, "/STACK:268435456")
#ifdef _DEBUG
	freopen("input.txt","rt",stdin);
	freopen("output.txt","wt",stdout);
#endif
	//#ifndef _DEBUG
	//  freopen("partit.in","rt",stdin);
	//  freopen("partit.out","wt",stdout);
	//#endif
	int k,i,j;

	scanf("%d%d%d",&n,&k,&x);
	g.resize(n);
	back.resize(n);
	c.resize(n);
	for(i=0;i<k;i++) {
		int a,b;
		double f;
		scanf("%d%d%lf",&a,&b,&f);
		g[a-1].push_back(b-1);
		g[b-1].push_back(a-1);
		c[a-1].push_back(f);
		c[b-1].push_back(-f);
		back[a-1].push_back(g[b-1].size()-1);
		back[b-1].push_back(g[a-1].size()-1);
	}

	double l=0.0,r=10000000.0;
	while(l<r-1e-7) {
		double m=(l+r)/2;
		if(check(m/(double)x)) l=m;
		else r=m;
	}

	printf("%.8lf",l);

	return 0;
}


#include <stdio.h>
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
#define ll long long int
#define mp make_pair
#define lli %I64d
ll mod = 1e9;
ll inf = 4 * 1e18;

vector<vector<int>> g,back;
vector<vector<double>> c,tek;
int n,x,d[1110],cur[1110];

bool bfs(int s,int f, double m) {
	queue<int> q;
	memset(d,-1,1110);
	d[s]=0;
	q.push(s);
	while(q.size()>0) {
		int v=q.front();
		for(int i=0;i<g[v].size();i++) {
			int to=g[v][i];
			if(d[to]==-1&&tek[v][i]>=m) {
				d[to]=d[v]+1;
				q.push(to);
				if(d[f]!=-1) return true;
			}
		}
		q.pop();
	}
	return false;
}

double dfs(int v,int f,double flow=mod) {
	if(v==f) return flow;
	if(flow<=0) return 0;
	for(;cur[v]<g[v].size();cur[v]++) {
		int to=g[v][cur[v]];
		if(d[to]==d[v]+1&&tek[v][cur[v]]>=flow) {
			double flownew=dfs(to,f,min(c[v][cur[v]],flow));
			if(flownew>0) {
				tek[v][cur[v]]-=flownew;
				tek[to][back[v][cur[v]]]+=flownew;
				return flownew;
			}
		}
	}
	return 0;
}

bool check(double m) {
	int kolmax=0;
	tek=c;
	while(bfs(0,n-1,m)) {
		memset(cur,0,1110);
		bool y=true;
		while(y) {
			double t=dfs(0,n-1,m);
			if(t!=m) y=false;
			else kolmax++;
			if(kolmax>=x) return true;
		}
	}
	return false;
}

int main() {
#pragma warning(disable: 4996)
#pragma comment(linker, "/STACK:268435456")
#ifdef _DEBUG
	freopen("input.txt","rt",stdin);
	freopen("output.txt","wt",stdout);
#endif
	//#ifndef _DEBUG
	//  freopen("partit.in","rt",stdin);
	//  freopen("partit.out","wt",stdout);
	//#endif
	int k,i,j;

	scanf("%d%d%d",&n,&k,&x);
	g.resize(n);
	back.resize(n);
	c.resize(n);
	for(i=0;i<k;i++) {
		int a,b;
		double f;
		scanf("%d%d%lf",&a,&b,&f);
		g[a-1].push_back(b-1);
		g[b-1].push_back(a-1);
		c[a-1].push_back(f);
		c[b-1].push_back(-f);
		back[a-1].push_back(g[b-1].size()-1);
		back[b-1].push_back(g[a-1].size()-1);
	}

	double l=0.0,r=1000000000.0;
	while(l<r-1e-9) {
		double m=(l+r)/2;
		if(check(m)) l=m;
		else r=m;
	}

	printf("%.8lf",(double)x*l);

	return 0;
}


#include <stdio.h>
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
#define ll long long int
#define mp make_pair
#define lli %I64d
ll mod = 1e9;
ll inf = 4 * 1e18;

vector<vector<int>> g,back;
vector<vector<double>> c,tek;
int n,x,d[1110],cur[1110];

bool bfs(int s,int f, double m) {
	queue<int> q;
	memset(d,-1,1110);
	d[s]=0;
	q.push(s);
	while(q.size()>0) {
		int v=q.front();
		for(int i=0;i<g[v].size();i++) {
			int to=g[v][i];
			if(d[to]==-1&&tek[v][i]>=m) {
				d[to]=d[v]+1;
				q.push(to);
				if(d[f]!=-1) return true;
			}
		}
		q.pop();
	}
	return false;
}

double dfs(int v,int f,double flow=mod) {
	if(v==f) return flow;
	if(flow<=0) return 0;
	for(;cur[v]<g[v].size();cur[v]++) {
		int to=g[v][cur[v]];
		if(d[to]==d[v]+1&&tek[v][cur[v]]>=flow) {
			double flownew=dfs(to,f,min(c[v][cur[v]],flow));
			if(flownew>0) {
				tek[v][cur[v]]-=flownew;
				tek[to][back[v][cur[v]]]+=flownew;
				return flownew;
			}
		}
	}
	return 0;
}

bool check(double m) {
	int kolmax=0;
	tek=c;
	while(bfs(0,n-1,m)) {
		memset(cur,0,1110);
		bool y=true;
		while(y) {
			double t=dfs(0,n-1,m);
			if(t!=m) y=false;
			else kolmax++;
			if(kolmax>=x) return true;
		}
	}
	return false;
}

int main() {
#pragma warning(disable: 4996)
#pragma comment(linker, "/STACK:268435456")
#ifdef _DEBUG
	freopen("input.txt","rt",stdin);
	freopen("output.txt","wt",stdout);
#endif
	//#ifndef _DEBUG
	//  freopen("partit.in","rt",stdin);
	//  freopen("partit.out","wt",stdout);
	//#endif
	int k,i,j;

	scanf("%d%d%d",&n,&k,&x);
	g.resize(n);
	back.resize(n);
	c.resize(n);
	for(i=0;i<k;i++) {
		int a,b;
		double f;
		scanf("%d%d%lf",&a,&b,&f);
		g[a-1].push_back(b-1);
		g[b-1].push_back(a-1);
		c[a-1].push_back(f);
		c[b-1].push_back(-f);
		back[a-1].push_back(g[b-1].size()-1);
		back[b-1].push_back(g[a-1].size()-1);
	}

	double l=0.0,r=1000000000.0;
	while(l<r-1e-13) {
		double m=(l+r)/2;
		if(check(m)) l=m;
		else r=m;
	}

	printf("%.8lf",(double)x*l);

	return 0;
}


#include <stdio.h>
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
#define ll long long int
#define mp make_pair
#define lli %I64d
ll mod = 1e9;
ll inf = 4 * 1e18;

vector<vector<int>> g,back;
vector<vector<double>> c,tek;
int n,x,d[1110],cur[1110];

bool bfs(int s,int f, double m) {
	queue<int> q;
	memset(d,-1,1110);
	d[s]=0;
	q.push(s);
	while(q.size()>0) {
		int v=q.front();
		for(int i=0;i<g[v].size();i++) {
			int to=g[v][i];
			if(d[to]==-1&&tek[v][i]>=m) {
				d[to]=d[v]+1;
				q.push(to);
				if(d[f]!=-1) return true;
			}
		}
		q.pop();
	}
	return false;
}

double dfs(int v,int f,double flow=mod) {
	if(v==f) return flow;
	if(flow<=0) return 0;
	for(;cur[v]<g[v].size();cur[v]++) {
		int to=g[v][cur[v]];
		if(d[to]==d[v]+1&&tek[v][cur[v]]>=flow) {
			double flownew=dfs(to,f,min(c[v][cur[v]],flow));
			if(flownew>0) {
				tek[v][cur[v]]-=flownew;
				tek[to][back[v][cur[v]]]+=flownew;
				return flownew;
			}
		}
	}
	return 0;
}

bool check(double m) {
	int kolmax=0;
	tek=c;
	while(bfs(0,n-1,m)) {
		memset(cur,0,1110);
		bool y=true;
		while(y) {
			double t=dfs(0,n-1,m);
			if(t!=m) y=false;
			else kolmax++;
			if(kolmax>=x) return true;
		}
	}
	return false;
}

int main() {
#pragma warning(disable: 4996)
#pragma comment(linker, "/STACK:268435456")
#ifdef _DEBUG
	freopen("input.txt","rt",stdin);
	freopen("output.txt","wt",stdout);
#endif
	//#ifndef _DEBUG
	//  freopen("partit.in","rt",stdin);
	//  freopen("partit.out","wt",stdout);
	//#endif
	int k,i,j;

	scanf("%d%d%d",&n,&k,&x);
	g.resize(n);
	back.resize(n);
	c.resize(n);
	for(i=0;i<k;i++) {
		int a,b;
		double f;
		scanf("%d%d%lf",&a,&b,&f);
		g[a-1].push_back(b-1);
		g[b-1].push_back(a-1);
		c[a-1].push_back(f);
		c[b-1].push_back(-f);
		back[a-1].push_back(g[b-1].size()-1);
		back[b-1].push_back(g[a-1].size()-1);
	}

	double l=0.0,r=1000000000.0;
	while(l<r-1e-7) {
		double m=(l+r)/2;
		if(check(m/(double)x)) l=m;
		else r=m;
	}

	printf("%.8lf",l);

	return 0;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-10;
const double EPS = 1e-10;

vector<int>e[SIZE];

int c[SIZE][SIZE], used[SIZE];
double cur[SIZE][SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i]] && cur[pos][e[pos][i]] + w < c[pos][e[pos][i]] + EPS)
		{
			cm = min(cm, (int)((c[pos][e[pos][i]] + EPS - cur[pos][e[pos][i]] ) / w));
			int t = get_path(e[pos][i], cm, w);
			if (t)
			{
				int step = min(t, cm);
				cur[pos][e[pos][i]] += step*w;
				cur[e[pos][i]][pos] -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			cur[i][j] = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c1;
		cin >> u >> v >> c1;
		u--;
		v--;
		e[u].push_back(v);
		e[v].push_back(u);
		c[u][v] = c1;
		c[v][u] = 0;
		maxc = max(maxc, c1);
	}
	double l = 0, r = m*maxc;
	for (int i = 0; i < 100; i++)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(10) << l * x;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-10;
const double EPS = 1e-8;

struct edge
{
	int v;
	double c, f;
	int rev;
};

vector<edge>e[SIZE];

int used[SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i].v] && e[pos][i].f + w < e[pos][i].c + EPS)
		{
			int cnt;
			if (w * x < e[pos][i].c + EPS - e[pos][i].f)
				cnt = x;
			else
				cnt = (int)((e[pos][i].c + EPS - e[pos][i].f ) / w);
			cm = min(cm, cnt);
			if (cm < 0)
				cm = 0;
			int t = get_path(e[pos][i].v, cm, w);
			if (t)
			{
				int step = min(t, cm);
				e[pos][i].f += step*w;
				e[e[pos][i].v][e[pos][i].rev].f -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < e[i].size(); j++)
			e[i][j].f = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c;
		cin >> u >> v >> c;
		u--;
		v--;
		edge t1, t2;
		t1.v = v;
		t2.v = u;
		t1.c = c;
		t2.c = 0;
		t1.f = t2.f = 0;
		e[u].push_back(t1);
		e[v].push_back(t2);
		e[u].back().rev = e[v].size()-1;
		e[v].back().rev = e[u].size()-1;
		maxc = max(maxc, c);
	}
	double l = 0, r = INT_MAX;
	for (int i = 0; i < 200; i++)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(10) << l * x;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-10;
const double EPS = 1e-10;

struct edge
{
	int v;
	double c, f;
	int rev;
};

vector<edge>e[SIZE];

int used[SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i].v] && e[pos][i].f + w < e[pos][i].c + EPS)
		{
			cm = min(cm, (int)((e[pos][i].c + EPS - e[pos][i].f ) / w));
			int t = get_path(e[pos][i].v, cm, w);
			if (t)
			{
				int step = min(t, cm);
				e[pos][i].f += step*w;
				e[e[pos][i].v][e[pos][i].rev].f -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < e[i].size(); j++)
			e[i][j].f = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c;
		cin >> u >> v >> c;
		u--;
		v--;
		edge t1, t2;
		t1.v = v;
		t2.v = u;
		t1.c = c;
		t2.c = 0;
		t1.f = t2.f = 0;
		e[u].push_back(t1);
		e[v].push_back(t2);
		e[u].back().rev = e[v].size()-1;
		e[v].back().rev = e[u].size()-1;
		maxc = max(maxc, c);
	}
	double l = 0, r = m*maxc;
	for (int i = 0; i < 300; i++)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(10) << l * x;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-12;

vector<int>e[SIZE];

int c[SIZE][SIZE], used[SIZE];
double cur[SIZE][SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i]] && cur[pos][e[pos][i]] + w < c[pos][e[pos][i]] + eps)
		{
			cm = min(cm, (int)((c[pos][e[pos][i]] + eps - cur[pos][e[pos][i]] ) / w));
			int t = get_path(e[pos][i], cm, w);
			if (t)
			{
				int step = min(t, cm);
				cur[pos][e[pos][i]] += step*w;
				cur[e[pos][i]][pos] -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			cur[i][j] = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c1;
		cin >> u >> v >> c1;
		u--;
		v--;
		e[u].push_back(v);
		e[v].push_back(u);
		c[u][v] = c1;
		c[v][u] = 0;
		maxc = max(maxc, c1);
	}
	double l = 0, r = m*maxc;
	while (abs(r-l) > eps)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(10) << l * x;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-10;

vector<int>e[SIZE];

int c[SIZE][SIZE], used[SIZE];
double cur[SIZE][SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i]] && cur[pos][e[pos][i]] + w < c[pos][e[pos][i]] + eps)
		{
			cm = min(cm, (int)((c[pos][e[pos][i]] + eps - cur[pos][e[pos][i]] ) / w));
			int t = get_path(e[pos][i], cm, w);
			if (t)
			{
				int step = min(t, cm);
				cur[pos][e[pos][i]] += step*w;
				cur[e[pos][i]][pos] -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			cur[i][j] = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c1;
		cin >> u >> v >> c1;
		u--;
		v--;
		e[u].push_back(v);
		e[v].push_back(u);
		c[u][v] = c1;
		c[v][u] = 0;
		maxc = max(maxc, c1);
	}
	double l = 0, r = m*maxc;
	while (abs(r-l) > eps)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(6) << l * x;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-10;
const double EPS = 1e-10;

struct edge
{
	int v;
	double c, f;
	int rev;
};

vector<edge>e[SIZE];

int used[SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i].v] && e[pos][i].f + w < e[pos][i].c + EPS)
		{
			cm = min(cm, (int)((e[pos][i].c + EPS - e[pos][i].f ) / w));
			int t = get_path(e[pos][i].v, cm, w);
			if (t)
			{
				int step = min(t, cm);
				e[pos][i].f += step*w;
				e[e[pos][i].v][e[pos][i].rev].f -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < e[i].size(); j++)
			e[i][j].f = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c;
		cin >> u >> v >> c;
		u--;
		v--;
		edge t1, t2;
		t1.v = v;
		t2.v = u;
		t1.c = c;
		t2.c = 0;
		t1.f = t2.f = 0;
		e[u].push_back(t1);
		e[v].push_back(t2);
		e[u].back().rev = e[v].size()-1;
		e[v].back().rev = e[u].size()-1;
		maxc = max(maxc, c);
	}
	double l = 0, r = m*maxc;
	for (int i = 0; i < 200; i++)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(10) << l * x;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-12;
const double EPS = 1e-12;

vector<int>e[SIZE];

int c[SIZE][SIZE], used[SIZE];
double cur[SIZE][SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i]] && cur[pos][e[pos][i]] + w < c[pos][e[pos][i]] + EPS)
		{
			cm = min(cm, (int)((c[pos][e[pos][i]] + EPS - cur[pos][e[pos][i]] ) / w));
			int t = get_path(e[pos][i], cm, w);
			if (t)
			{
				int step = min(t, cm);
				cur[pos][e[pos][i]] += step*w;
				cur[e[pos][i]][pos] -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			cur[i][j] = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c1;
		cin >> u >> v >> c1;
		u--;
		v--;
		e[u].push_back(v);
		e[v].push_back(u);
		c[u][v] = c1;
		c[v][u] = 0;
		maxc = max(maxc, c1);
	}
	double l = 0, r = m*maxc;
	while (abs(r-l)*x > eps)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(10) << l * x;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-10;
const double EPS = 1e-10;

struct edge
{
	int v;
	double c, f;
	int rev;
};

vector<edge>e[SIZE];

int used[SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i].v] && e[pos][i].f + w < e[pos][i].c + EPS)
		{
			cm = min(cm, (int)((e[pos][i].c + EPS - e[pos][i].f ) / w));
			int t = get_path(e[pos][i].v, cm, w);
			if (t)
			{
				int step = min(t, cm);
				e[pos][i].f += step*w;
				e[e[pos][i].v][e[pos][i].rev].f -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < e[i].size(); j++)
			e[i][j].f = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c;
		cin >> u >> v >> c;
		u--;
		v--;
		edge t1, t2;
		t1.v = v;
		t2.v = u;
		t1.c = c;
		t2.c = 0;
		t1.f = t2.f = 0;
		e[u].push_back(t1);
		e[v].push_back(t2);
		e[u].back().rev = e[v].size()-1;
		e[v].back().rev = e[u].size()-1;
		maxc = max(maxc, c);
	}
	double l = 0, r = INT_MAX;
	for (int i = 0; i < 200; i++)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(10) << l * x;
}


#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <climits>

using namespace std;

const int SIZE = 100;
const double eps = 1e-10;
const double EPS = 1e-10;

struct edge
{
	int v;
	double c, f;
	int rev;
};

vector<edge>e[SIZE];

int used[SIZE];
int n, m, x;

int get_path(int pos, int cm, double w)
{
	used[pos] = 1;
	if (pos == n-1)
		return x;
	for (int i = 0; i < e[pos].size(); i++)
	{
		if (!used[e[pos][i].v] && e[pos][i].f + w < e[pos][i].c + EPS)
		{
			cm = min(cm, (int)((e[pos][i].c + EPS - e[pos][i].f ) / w));
			int t = get_path(e[pos][i].v, cm, w);
			if (t)
			{
				int step = min(t, cm);
				e[pos][i].f += step*w;
				e[e[pos][i].v][e[pos][i].rev].f -= step*w;
				return step;
			}
		}
	}
	return 0;
}

int check(double w)
{
	for (int i = 0; i < n; i++)
		for (int j = 0; j < e[i].size(); j++)
			e[i][j].f = 0;
	int cnt = 0;
	for(;;)
	{
		for (int i = 0; i < n; i++)
			used[i] = 0;
		int t = get_path(0, x, w);
		if (t == 0)
			return 0;
		cnt += t;
		if (cnt >= x)
			return 1;
	}
}

int main()
{
#ifdef LOCAL
   freopen( "input.txt", "rt", stdin );
   freopen( "output.txt", "wt", stdout );
#endif
	int maxc;
	cin >> n >> m >> x;
	for (int i = 0; i < m; i++)
	{
		int u, v, c;
		cin >> u >> v >> c;
		u--;
		v--;
		edge t1, t2;
		t1.v = v;
		t2.v = u;
		t1.c = c;
		t2.c = 0;
		t1.f = t2.f = 0;
		e[u].push_back(t1);
		e[v].push_back(t2);
		e[u].back().rev = e[v].size()-1;
		e[v].back().rev = e[u].size()-1;
		maxc = max(maxc, c);
	}
	double l = 0, r = INT_MAX;
	for (int i = 0; i < 100; i++)
	{
		double m = (r+l)/2;
		if (check(m))
			l = m;
		else
			r = m;
	}
	cout << fixed << setprecision(10) << l * x;
}


//#define TSOGU
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <string>
#include <algorithm>
#include <random>
using namespace std;

int n, m, x;
int a[510], b[510], c[510];

struct edge
{
	long long cap, flow;
} G[60][60];
int s, t;

long long d[60], ptr[60];

void bfs(int s)
{
	char u[228];
	memset(u, 0, sizeof u);
	memset(d, -1, sizeof d);
	d[s] = 0;
	queue <int> q;
	q.push(s);
	u[s] = 1;
	while (!q.empty())
	{
		int v = q.front();
		q.pop();
		for (int i = s; i <= t; ++i)
		{
			if (!u[i] && G[v][i].cap - G[v][i].flow > 0)
			{
				d[i] = d[v] + 1;
				u[i] = 1;
				q.push(i);
			}
		}
	}
}

long long dfs(int v, long long pushed)
{
	if (v == t)
		return pushed;
	if (pushed == 0)
		return 0;
	for (int i = ptr[v]; i <= t; ++i)
	{
		if (d[i] == d[v] + 1)
		{
			long long x = dfs(i, min(pushed, G[v][i].cap - G[v][i].flow));
			if (x)
			{
				G[v][i].flow += x;
				G[i][v].flow -= x;
				return x;
			}
		}
	}
	return 0;
}

long long dinic()
{
	int ans = 0;
	while (true)
	{
		bfs(s);
		if (d[t] == -1)
			break;
		memset(ptr, 0, sizeof ptr);
		while (long long x = dfs(s, 100000))
			ans += x;
	}
	return ans;
}

int main()
{
#ifdef TSOGU
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif

	scanf("%d %d %d", &n, &m, &x);
	for (int i = 1; i <= m; ++i)
		scanf("%d %d %d", &a[i], &b[i], &c[i]);
	s = 1, t = n;

	long double ll = 0.0, rr = 1e15;
	for (int iter = 0; iter < 300; ++iter)
	{
		long double mid = (ll + rr)/2.0;
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				G[i][j].cap = G[i][j].flow = 0;
		for (int i = 1; i <= m; ++i)
		{
			long long cnt = c[i]/(mid/x);
			G[a[i]][b[i]].cap = cnt;
		}

		long long total = dinic();
		if (total >= x)
			ll = mid;
		else
			rr = mid;
	}

	double ans = double(ll + rr)/2.0;
	printf("%.8lf\n", ans);

	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <cstring>
#include <ctime>
#include <cassert>

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <numeric>
#include <deque>
#include <stdio.h>
#include <set>
#include <map>
#include <unordered_map>
using namespace std;

#define x first
#define y second
#define mp make_pair
#define all(a) a.begin(), a.end()
#define sqr(x) ((x) * (x))
#define forn(i, n) for (int i = 0; i < (n); i++)

typedef long long li;
typedef long double ld;

const int INF = (int) 1e9;
const li INF64 = (li) 1e18;
const int N = 52;

long long cur;
bool used[N];

int s, t;

struct edge
{
	int to;
	li cap;

	edge(int to, li cap)
	{
		this->to = to;
		this->cap = cap;
	}

	edge() :to(0), cap(0)
	{

	}
};

vector <edge> edges;
vector <int> g[N];

inline void add(int a, int b, li cap, li cap2)
{
	g[a].push_back(edges.size());
	edges.push_back(edge(b, cap));
	g[b].push_back(edges.size());
	edges.push_back(edge(a, cap2));
}

bool dfs(int v)
{
	used[v] = true;
	if (v == t)
	{
		return true;
	}

	for (int i = 0; i < g[v].size(); i++)
	{
		int idx = g[v][i];
		if (!used[edges[idx].to] && edges[idx].cap >= cur && dfs(edges[idx].to))
		{
			edges[idx].cap -= cur;
			edges[idx ^ 1].cap += cur;
			return true;
		}
	}

	return false;
}

li flow() {

	li ans = 0;
	cur = 1000001;

	while (cur > 0)
	{
		memset(used, false, sizeof(used));
		if (!dfs(s))
		{
			cur = (cur >> 1);
		}
		else
		{
			ans += cur;
		}
	}
	return ans;
}

vector<pair<pair<int, int>, int>> graph;

int n, m, bears;

bool check(double x) {
	for (int i = 0; i < N; i++) {
		g[i].clear();
		used[i] = false;
	}
	edges.clear();
	for (int i = 0; i < m; i++) {
		li cost = (li)((double)(graph[i].second) / x);

		int from = graph[i].first.first;
		int to = graph[i].first.second;
		add(from, to, cost, 0);
	}

	return flow() >= (li)bears;
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	scanf("%d %d %d", &n, &m, &bears);
	for (int i = 0; i < m; i++) {
		int from, to, cost;
		scanf("%d %d %d", &from, &to, &cost);
		from--; to--;
		graph.push_back(mp(mp(from, to), cost));
	}

	s = 0; t = n - 1;

	double l = 0.0;
	double r = 1000001.0;

	for (int i = 0; i < 70; i++) {
		double mid = (l + r) / 2.0;
		if (check(mid)) {
			l = mid;
		}
		else {
			r = mid;
		}
	}

	double ans = ((l + r) / 2.0) * (double)bears;
	printf("%.15f", ans);
	return 0;
}