#include <bits/stdc++.h>

#define F first
#define S second
#define pb push_back
#define ll long long

using namespace std;

const ll inf = 1e18;
const int mod = 1e9 + 7;

long double a[505], b[505], c[505];
vector <int> used(51);
vector <vector <int> > g;
int n,m,x;

int dfs(int v, int pushed){
  if (v == n) return pushed;
  int flow = 0;
  used[v] = 1;
  for (int i=1;i<=n;i++){
    if (!used[i]  && g[v][i]){
      int cur = dfs(i, min(pushed,g[v][i]));
      flow += cur;
      pushed -= cur;
      g[v][i] -= cur;
      g[i][v] += cur;
    }
  }
  return flow;
}

int maxflow(){
  int flow = 0;
  //used.resize(n);
  used.assign(n,0);
  int add = dfs(1,1e9);
  while (add){
    flow += add;
    used.assign(n,0);
    add = dfs(1,1e9);
  }
  return flow;
}

bool check(long double k){
  for (int i=0;i<m;i++){
    g[a[i]][b[i]] = floor(c[i] / k);
  }
  if (maxflow() >= x)  return true;
  return false;
}

int main(){
  ios_base::sync_with_stdio(0);
  //freopen("input.txt", r, stdin);
  //freopen("output.txt", w, stdout);
  cin >> n >> m >> x;
  g.resize(n+1);
  for (int i=0;i<=n;i++){
    g[i].resize(n+1);
  }
  for (int i=0;i<m;i++){
    cin >> a[i] >> b[i] >> c[i];
  }
  long double l = 0.0, r = 1000001.0;
  for (int i=0;i<228;i++){
    long double mid = (l + r) * 0.5;
    if (check(mid)) l = mid;
    else r = mid;
  }
  cout << fixed << setprecision(10) << l * x << endl;
}


#include <bits/stdc++.h>

#define F first
#define S second
#define pb push_back
#define ll long long

using namespace std;

const ll inf = 1e18;
const int mod = 1e9 + 7;

long double a[505], b[505], c[505];
vector <int> used(51);
vector <vector <int> > g;
int n,m,x;

int dfs(int v, int pushed){
  if (v == n) return pushed;
  int flow = 0;
  used[v] = 1;
  for (int i=1;i<=n;i++){
    if (!used[i]  && g[v][i]){
      int cur = dfs(i, min(pushed,g[v][i]));
      flow += cur;
      pushed -= cur;
      g[v][i] -= cur;
      g[i][v] += cur;
    }
  }
  return flow;
}

int maxflow(){
  int flow = 0;
  //used.resize(n);
  used.assign(n,0);
  int add = dfs(1,1e9);
  while (add){
    flow += add;
    used.assign(n,0);
    add = dfs(1,1e9);
  }
  return flow;
}

bool check(long double k){
  for (int i=0;i<m;i++){
    g[a[i]][b[i]] = floor(c[i] / k);
  }
  if (maxflow() >= x)  return true;
  return false;
}

int main(){
  ios_base::sync_with_stdio(0);
  //freopen("input.txt", r, stdin);
  //freopen("output.txt", w, stdout);
  cin >> n >> m >> x;
  g.resize(n+1);
  for (int i=0;i<=n;i++){
    g[i].resize(n+1);
  }
  for (int i=0;i<m;i++){
    cin >> a[i] >> b[i] >> c[i];
  }
  long double l = 0.0, r = 1000001.0;
  for (int i=0;i<100;i++){
    long double mid = (l + r) * 0.5;
    if (check(mid)) l = mid;
    else r = mid;
  }
  cout << fixed << setprecision(10) << l * x << endl;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){
		vector<int>a(m),b(m),c(m);
		rep(i,0,m){
			cin>>a[i]>>b[i]>>c[i];
		}
		double s=0.0,e=50000000;
		double ans=0;
		rep(i,0,100){
			double mid=(e+s)/2.0;
			Dinic d(n+2);
			rep(i,0,m)d.AddEdge(a[i],b[i],c[i]/mid);
			d.AddEdge(n,n+1,INF);
			d.GetMaxFlow(1,n+1);
			int tmp=0;
			int j=d.G[n].size()-1;
			if(d.G[n][j].to==n+1)tmp=d.G[n][j].flow;
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(7)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){

		Dinic d(n+1);
		rep(i,0,m){
			int a,b,c;
			cin>>a>>b>>c;
			d.AddEdge(a,b,c);
		}
		d.GetMaxFlow(1,n);
		vector<int>v;
		rep(i,0,d.G.size()){
			rep(j,0,d.G[i].size()){
				//cout<<d.G[i][j].from<<"->"<<d.G[i][j].to<<"("<<d.G[i][j].flow<<") ";
				if(d.G[i][j].to==n)v.push_back(d.G[i][j].flow);
			}//cout<<endl;
		}

		double s=0.0,e=*max_element(all(v));
		double ans=0;
		while(e-s>1e-10){
			double mid=(e+s)/2.0;
			int tmp=0;
			rep(i,0,v.size()){
				tmp+=(v[i]/mid);
			}
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(8)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){

		Dinic d(2*n+3);
		repe(i,1,n)d.AddEdge(i,i+n,INF),d.AddEdge(i+n,i,INF);
		rep(i,0,m){
			int a,b,c;
			cin>>a>>b>>c;
			d.AddEdge(a,b+n,c);
		}
		d.GetMaxFlow(1,2*n);
		vector<int>v;
		rep(i,0,d.G.size()){
			rep(j,0,d.G[i].size()){
				//cout<<d.G[i][j].from<<"->"<<d.G[i][j].to<<"("<<d.G[i][j].flow<<") ";
				if(d.G[i][j].from<n&&d.G[i][j].to==2*n)v.push_back(d.G[i][j].flow);
			}//cout<<endl;
		}
		//rep(i,0,v.size())cout<<v[i]<<endl;

		double s=0.0,e=*max_element(all(v));
		double ans=0;
		while(e-s>1e-10){
			double mid=(e+s)/2.0;
			int tmp=0;
			rep(i,0,v.size()){
				tmp+=(v[i]/mid);
			}
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(8)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){

		Dinic d(2*n+3);
		repe(i,1,n)d.AddEdge(i,i+n,INF),d.AddEdge(i+n,i,INF);
		rep(i,0,m){
			int a,b,c;
			cin>>a>>b>>c;
			d.AddEdge(a,b+n,c);
			d.AddEdge(a+n,b,c);
		}
		d.GetMaxFlow(1,2*n);
		vector<int>v;
		rep(i,0,d.G.size()){
			rep(j,0,d.G[i].size()){
				//cout<<d.G[i][j].from<<"->"<<d.G[i][j].to<<"("<<d.G[i][j].flow<<") ";
				if(d.G[i][j].from<n&&d.G[i][j].to==2*n)v.push_back(d.G[i][j].flow);
			}//cout<<endl;
		}

		double s=0.0,e=*max_element(all(v));
		double ans=0;
		while(e-s>1e-10){
			double mid=(e+s)/2.0;
			int tmp=0;
			rep(i,0,v.size()){
				tmp+=(v[i]/mid);
			}
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(8)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){
		vector<int>a(m),b(m),c(m);
		rep(i,0,m){
			cin>>a[i]>>b[i]>>c[i];
		}
		double s=0.0,e=1e9;
		double ans=0;
		rep(i,0,120){
			double mid=(e+s)/2.0;
			Dinic d(n+2);
			rep(i,0,m)d.AddEdge(a[i],b[i],c[i]/mid);
			d.AddEdge(n,n+1,INF);
			d.GetMaxFlow(1,n+1);
			ll tmp=0;
			int j=d.G[n].size()-1;
			if(d.G[n][j].to==n+1)tmp=d.G[n][j].flow;
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(7)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){
		vector<int>a(m),b(m),c(m);
		rep(i,0,m){
			cin>>a[i]>>b[i]>>c[i];
		}
		double s=0.0,e=1e6+10;
		double ans=0;
		while(e-s>1e-10){
			double mid=(e+s)/2.0;
			Dinic d(n+2);
			rep(i,0,m)d.AddEdge(a[i],b[i],c[i]/mid);
			d.AddEdge(n,n+1,INF);
			d.GetMaxFlow(1,n+1);
			int tmp=0;
			rep(j,0,d.G[n].size())if(d.G[n][j].to==n+1)tmp=d.G[n][j].flow;
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(9)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);
	//int cnt=0;
	//rep(i,1,51)repe(j,i+1,50){cout<<i<<" "<<j<<" "<<10000000<<endl;cnt++;if(cnt==500)return 0;}
	//cout<<cnt<<endl;
	int n,m,x;
	while(cin>>n>>m>>x){
		Dinic d(n+1);
		rep(i,0,m){
			int a,b,c;
			cin>>a>>b>>c;
			d.AddEdge(a,b,c);
		}
		d.GetMaxFlow(1,n);
		vector<ll>v;
		rep(i,0,d.G.size()){
			rep(j,0,d.G[i].size()){
				//cout<<d.G[i][j].from<<"->"<<d.G[i][j].to<<"("<<d.G[i][j].flow<<") ";
				if(d.G[i][j].to==n)v.push_back(d.G[i][j].flow);
			}//cout<<endl;
		}

		double s=0.0,e=1e6+10;
		double ans=0;
		while(e-s>1e-10){
			double mid=(e+s)/2.0;
			ll tmp=0;
			rep(i,0,v.size()){
				tmp+=(v[i]/mid);
			}
			//cout<<"tmpppppp "<<tmp<<endl;
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(9)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){
		vector<int>a(m),b(m),c(m);
		rep(i,0,m){
			cin>>a[i]>>b[i]>>c[i];
		}
		/*vector<int>v;
		rep(i,0,d.G.size()){
			rep(j,0,d.G[i].size()){
				//cout<<d.G[i][j].from<<"->"<<d.G[i][j].to<<"("<<d.G[i][j].flow<<") ";
				if(d.G[i][j].to==n)v.push_back(d.G[i][j].flow);
			}//cout<<endl;
		}*/

		double s=0.0,e=1e6+10;
		double ans=0;
		while(e-s>1e-10){
			double mid=(e+s)/2.0;
			Dinic d(n+2);
			rep(i,0,m)d.AddEdge(a[i],b[i],c[i]/mid);
			d.AddEdge(n,n+1,INF);
			d.GetMaxFlow(1,n+1);
			int tmp=0;
			rep(i,0,d.G.size())rep(j,0,d.G[i].size())if(d.G[i][j].from==n&&d.G[i][j].to==n+1)tmp=d.G[i][j].flow;
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(9)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000;

struct Edge {
    int from, to, cap, flow, index;
    Edge(int from, int to, int cap, int flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, int cap) {
        G[from].push_back(Edge(from, to, cap, 0, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0, 0, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            int amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){
		vector<int>a(m),b(m),c(m);
		rep(i,0,m){
			cin>>a[i]>>b[i]>>c[i];
		}
		double s=0.0,e=1e6+10;
		double ans=0;
		while(e-s>1e-10){
			double mid=(e+s)/2.0;
			Dinic d(n+2);
			rep(i,0,m)d.AddEdge(a[i],b[i],c[i]/mid);
			d.AddEdge(n,n+1,INF);
			d.GetMaxFlow(1,n+1);
			int tmp=0;
			int j=d.G[n].size()-1;
			if(d.G[n][j].to==n+1)tmp=d.G[n][j].flow;
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(9)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(i,x,n) for(int i=x;i<n;i++)
#define repe(i,x,n) for(int i=x;i<=n;i++)
#define repn(i,x,n) for(int i=x;i>=n;i--)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define F first
#define S second
#define mod 1000000007

typedef long long ll;

const double PI=3.14159265359;

const int INF = 2000000000000000000;

struct Edge {
	int from, to, index;
	ll flow, cap;
    Edge(int from, int to, ll cap, ll flow, int index) :
        from(from), to(to), cap(cap), flow(flow), index(index) { }
};

struct Dinic {
    int N;
    vector<vector<Edge> > G;
    vector<Edge *> dad;
    vector<int> Q;

    Dinic(int N) : N(N), G(N), dad(N), Q(N) { }

    void AddEdge(int from, int to, ll cap) {
        G[from].push_back(Edge(from, to, cap, 0ll, G[to].size()));
        if(from == to) G[from].back().index++;
        G[to].push_back(Edge(to, from, 0ll, 0ll, G[from].size() - 1));
    }

    long long BlockingFlow(int s, int t) {
        fill(dad.begin(), dad.end(), (Edge *)NULL);
        dad[s] = &G[0][0] - 1;

        int head = 0, tail = 0;
        Q[tail++] = s;
        while(head < tail) {
            int x = Q[head++];
            for(int i = 0; i < G[x].size(); i++) {
                Edge &e = G[x][i];
                if(!dad[e.to] && e.cap - e.flow > 0) {
                    dad[e.to] = &G[x][i];
                    Q[tail++] = e.to;
                }
            }
        }
        if(!dad[t]) return 0;

        long long totflow = 0;
        for(int i = 0; i < G[t].size(); i++) {
            Edge *start = &G[G[t][i].to][G[t][i].index];
            ll amt = INF;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                if(!e) {
                    amt = 0;
                    break;
                }
                amt = min(amt, e->cap - e->flow);
            }
            if(amt == 0) continue;
            for(Edge *e = start; amt && e != dad[s]; e = dad[e->from]) {
                e->flow += amt;
                G[e->to][e->index].flow -= amt;
            }
            totflow += amt;
        }
        return totflow;
    }

    long long GetMaxFlow(int s, int t) {
        long long totflow = 0;
        while(long long flow = BlockingFlow(s, t))
            totflow += flow;
        return totflow;
    }
};

int main()
{
	ios::sync_with_stdio(false);

	int n,m,x;
	while(cin>>n>>m>>x){
		vector<ll>a(m),b(m),c(m);
		rep(i,0,m){
			cin>>a[i]>>b[i]>>c[i];
		}
		double s=0.0,e=1e9;
		double ans=0;
		rep(i,0,100){
			double mid=(e+s)/2.0;
			Dinic d(n+2);
			rep(i,0,m)d.AddEdge(a[i],b[i],c[i]/mid);
			d.AddEdge(n,n+1,INF);
			d.GetMaxFlow(1,n+1);
			ll tmp=0;
			int j=d.G[n].size()-1;
			if(d.G[n][j].to==n+1)tmp=d.G[n][j].flow;
			if(tmp<x)e=mid;
			else s=mid,ans=mid;
		}
		ans*=(double)x;
		cout<<fixed<<setprecision(7)<<ans<<"\n";
	}

	return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define MOD 1000000007
#define EPS 1e-9
#define INF 1000000002

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<pii, int> piii;
const int N = 100001;
int n,m;

struct FlowEdge {
    int v, u;
    long long cap, flow = 0;
    FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
};

struct Dinic {
    const long long flow_inf = 1e18;
    vector<FlowEdge> edges;
    vector<vector<int>> adj;
    int n, m = 0;
    int s, t;
    vector<int> level, ptr;
    queue<int> q;

    Dinic(int n, int s, int t) : n(n), s(s), t(t) {
        adj.resize(n);
        level.resize(n);
        ptr.resize(n);
    }

    ~Dinic() {
        edges.clear();
        adj.clear();
        level.clear();
        ptr.clear();
        q = queue<int>();
    }

    void add_edge(int v, int u, long long cap) {
        edges.emplace_back(v, u, cap);
        edges.emplace_back(u, v, 0);
        adj[v].push_back(m);
        adj[u].push_back(m + 1);
        m += 2;
    }

    bool bfs() {
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int id : adj[v]) {
                if (edges[id].cap - edges[id].flow < 1)
                    continue;
                if (level[edges[id].u] != -1)
                    continue;
                level[edges[id].u] = level[v] + 1;
                q.push(edges[id].u);
            }
        }
        return level[t] != -1;
    }

    long long dfs(int v, long long pushed) {
        if (pushed == 0)
            return 0;
        if (v == t)
            return pushed;
        for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) {
            int id = adj[v][cid];
            int u = edges[id].u;
            if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
                continue;
            long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
            if (tr == 0)
                continue;
            edges[id].flow += tr;
            edges[id ^ 1].flow -= tr;
            return tr;
        }
        return 0;
    }

    long long flow() {
        long long f = 0;
        while (true) {
            fill(level.begin(), level.end(), -1);
            level[s] = 0;
            q.push(s);
            if (!bfs())
                break;
            fill(ptr.begin(), ptr.end(), 0);
            while (long long pushed = dfs(s, flow_inf)) {
                f += pushed;
            }
        }
        return f;
    }
};

int main() {
    int n, m, x;
    scanf("%d%d%d",&n,&m,&x);
    vector<piii> edges;
    while(m--) {
        int x, y, c;
        scanf("%d%d%d",&x,&y,&c);
        x--, y--;
        edges.pb({{x, y}, c});
    }
    double l = 0, r = 1e6;
    int cnt = 200;
    while(cnt--) {
        Dinic* dinic = new Dinic(n, 0, n-1);
        double mid = (l+r)/2;
        for(piii p : edges) {
            dinic->add_edge(p.f.f, p.f.s, p.s/mid+EPS);
        }
        int y = dinic->flow();
//        cout<<mid<<" "<<y<<endl;
        if (y >= x) {
            l = mid;
        } else {
            r = mid;
        }
        delete dinic;
    }
    printf("%0.6f", l*x);
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define MOD 1000000007
#define EPS 1e-10
#define INF 1000000002

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<pii, int> piii;
const int N = 100001;
int n,m;

struct FlowEdge {
    int v, u;
    long long cap, flow = 0;
    FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
};

struct Dinic {
    const long long flow_inf = 1e18;
    vector<FlowEdge> edges;
    vector<vector<int>> adj;
    int n, m = 0;
    int s, t;
    vector<int> level, ptr;
    queue<int> q;

    Dinic(int n, int s, int t) : n(n), s(s), t(t) {
        adj.resize(n);
        level.resize(n);
        ptr.resize(n);
    }

    ~Dinic() {
        edges.clear();
        adj.clear();
        level.clear();
        ptr.clear();
        q = queue<int>();
    }

    void add_edge(int v, int u, long long cap) {
        edges.emplace_back(v, u, cap);
        edges.emplace_back(u, v, 0);
        adj[v].push_back(m);
        adj[u].push_back(m + 1);
        m += 2;
    }

    bool bfs() {
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int id : adj[v]) {
                if (edges[id].cap - edges[id].flow < 1)
                    continue;
                if (level[edges[id].u] != -1)
                    continue;
                level[edges[id].u] = level[v] + 1;
                q.push(edges[id].u);
            }
        }
        return level[t] != -1;
    }

    long long dfs(int v, long long pushed) {
        if (pushed == 0)
            return 0;
        if (v == t)
            return pushed;
        for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) {
            int id = adj[v][cid];
            int u = edges[id].u;
            if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
                continue;
            long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
            if (tr == 0)
                continue;
            edges[id].flow += tr;
            edges[id ^ 1].flow -= tr;
            return tr;
        }
        return 0;
    }

    long long flow() {
        long long f = 0;
        while (true) {
            fill(level.begin(), level.end(), -1);
            level[s] = 0;
            q.push(s);
            if (!bfs())
                break;
            fill(ptr.begin(), ptr.end(), 0);
            while (long long pushed = dfs(s, flow_inf)) {
                f += pushed;
            }
        }
        return f;
    }
};

int main() {
    int n, m, x;
    scanf("%d%d%d",&n,&m,&x);
    vector<piii> edges;
    while(m--) {
        int x, y, c;
        scanf("%d%d%d",&x,&y,&c);
        x--, y--;
        edges.pb({{x, y}, c});
    }
    double l = 0, r = 1e6;
    while(r-l>=EPS) {
        Dinic* dinic = new Dinic(n, 0, n-1);
        double mid = (l+r)/2;
        for(piii p : edges) {
            dinic->add_edge(p.f.f, p.f.s, p.s/mid+EPS);
        }
        int y = dinic->flow();
//        cout<<mid<<" "<<y<<endl;
        if (y >= x) {
            l = mid;
        } else {
            r = mid;
        }
        delete dinic;
    }
    printf("%0.6f", l*x);
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define MOD 1000000007
#define EPS 1e-10
#define INF 1000000002

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<pii, int> piii;
const int N = 100001;
int n,m;

struct FlowEdge {
    int v, u;
    long long cap, flow = 0;
    FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
};

struct Dinic {
    const long long flow_inf = 1e18;
    vector<FlowEdge> edges;
    vector<vector<int>> adj;
    int n, m = 0;
    int s, t;
    vector<int> level, ptr;
    queue<int> q;

    Dinic(int n, int s, int t) : n(n), s(s), t(t) {
        adj.resize(n);
        level.resize(n);
        ptr.resize(n);
    }

    ~Dinic() {
        edges.clear();
        adj.clear();
        level.clear();
        ptr.clear();
        q = queue<int>();
    }

    void add_edge(int v, int u, long long cap) {
        edges.emplace_back(v, u, cap);
        edges.emplace_back(u, v, 0);
        adj[v].push_back(m);
        adj[u].push_back(m + 1);
        m += 2;
    }

    bool bfs() {
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int id : adj[v]) {
                if (edges[id].cap - edges[id].flow < 1)
                    continue;
                if (level[edges[id].u] != -1)
                    continue;
                level[edges[id].u] = level[v] + 1;
                q.push(edges[id].u);
            }
        }
        return level[t] != -1;
    }

    long long dfs(int v, long long pushed) {
        if (pushed == 0)
            return 0;
        if (v == t)
            return pushed;
        for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) {
            int id = adj[v][cid];
            int u = edges[id].u;
            if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
                continue;
            long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
            if (tr == 0)
                continue;
            edges[id].flow += tr;
            edges[id ^ 1].flow -= tr;
            return tr;
        }
        return 0;
    }

    long long flow() {
        long long f = 0;
        while (true) {
            fill(level.begin(), level.end(), -1);
            level[s] = 0;
            q.push(s);
            if (!bfs())
                break;
            fill(ptr.begin(), ptr.end(), 0);
            while (long long pushed = dfs(s, flow_inf)) {
                f += pushed;
            }
        }
        return f;
    }
};

int main() {
    int n, m, x;
    scanf("%d%d%d",&n,&m,&x);
    vector<piii> edges;
    while(m--) {
        int x, y, c;
        scanf("%d%d%d",&x,&y,&c);
        x--, y--;
        edges.pb({{x, y}, c});
    }
    double l = 0, r = INF;
    while(r-l>=EPS) {
        Dinic* dinic = new Dinic(n, 0, n-1);
        double mid = (l+r)/2;
        for(piii p : edges) {
            dinic->add_edge(p.f.f, p.f.s, p.s/mid+EPS);
        }
        int y = dinic->flow();
        if (y >= x) {
            l = mid;
        } else {
            r = mid;
        }
        delete dinic;
    }
    printf("%0.7f", l*x);
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define MOD 1000000007
#define EPS 1e-9
#define INF 1000000002

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<pii, int> piii;
const int N = 100001;
int n,m;

struct FlowEdge {
    int v, u;
    long long cap, flow = 0;
    FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
};

struct Dinic {
    const long long flow_inf = 1e18;
    vector<FlowEdge> edges;
    vector<vector<int>> adj;
    int n, m = 0;
    int s, t;
    vector<int> level, ptr;
    queue<int> q;

    Dinic(int n, int s, int t) : n(n), s(s), t(t) {
        adj.resize(n);
        level.resize(n);
        ptr.resize(n);
    }

    ~Dinic() {
        edges.clear();
        adj.clear();
        level.clear();
        ptr.clear();
        q = queue<int>();
    }

    void add_edge(int v, int u, long long cap) {
        edges.emplace_back(v, u, cap);
        edges.emplace_back(u, v, 0);
        adj[v].push_back(m);
        adj[u].push_back(m + 1);
        m += 2;
    }

    bool bfs() {
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int id : adj[v]) {
                if (edges[id].cap - edges[id].flow < 1)
                    continue;
                if (level[edges[id].u] != -1)
                    continue;
                level[edges[id].u] = level[v] + 1;
                q.push(edges[id].u);
            }
        }
        return level[t] != -1;
    }

    long long dfs(int v, long long pushed) {
        if (pushed == 0)
            return 0;
        if (v == t)
            return pushed;
        for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) {
            int id = adj[v][cid];
            int u = edges[id].u;
            if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
                continue;
            long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
            if (tr == 0)
                continue;
            edges[id].flow += tr;
            edges[id ^ 1].flow -= tr;
            return tr;
        }
        return 0;
    }

    long long flow() {
        long long f = 0;
        while (true) {
            fill(level.begin(), level.end(), -1);
            level[s] = 0;
            q.push(s);
            if (!bfs())
                break;
            fill(ptr.begin(), ptr.end(), 0);
            while (long long pushed = dfs(s, flow_inf)) {
                f += pushed;
            }
        }
        return f;
    }
};

int main() {
    int n, m, x;
    scanf("%d%d%d",&n,&m,&x);
    vector<piii> edges;
    while(m--) {
        int x, y, c;
        scanf("%d%d%d",&x,&y,&c);
        x--, y--;
        edges.pb({{x, y}, c});
    }
    double l = 0, r = 1e6;
    while(r-l>=EPS) {
        Dinic* dinic = new Dinic(n, 0, n-1);
        double mid = (l+r)/2;
        for(piii p : edges) {
            dinic->add_edge(p.f.f, p.f.s, p.s/mid+EPS);
        }
        int y = dinic->flow();
//        cout<<mid<<" "<<y<<endl;
        if (y >= x) {
            l = mid;
        } else {
            r = mid;
        }
        delete dinic;
    }
    printf("%0.6f", l*x);
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define MOD 1000000007
#define EPS 1e-11
#define INF 1000000002

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<pii, int> piii;
const int N = 100001;
int n,m;

struct FlowEdge {
    int v, u;
    long long cap, flow = 0;
    FlowEdge(int v, int u, long long cap) : v(v), u(u), cap(cap) {}
};

struct Dinic {
    const long long flow_inf = 1e18;
    vector<FlowEdge> edges;
    vector<vector<int>> adj;
    int n, m = 0;
    int s, t;
    vector<int> level, ptr;
    queue<int> q;

    Dinic(int n, int s, int t) : n(n), s(s), t(t) {
        adj.resize(n);
        level.resize(n);
        ptr.resize(n);
    }

    ~Dinic() {
        edges.clear();
        adj.clear();
        level.clear();
        ptr.clear();
        q = queue<int>();
    }

    void add_edge(int v, int u, long long cap) {
        edges.emplace_back(v, u, cap);
        edges.emplace_back(u, v, 0);
        adj[v].push_back(m);
        adj[u].push_back(m + 1);
        m += 2;
    }

    bool bfs() {
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (int id : adj[v]) {
                if (edges[id].cap - edges[id].flow < 1)
                    continue;
                if (level[edges[id].u] != -1)
                    continue;
                level[edges[id].u] = level[v] + 1;
                q.push(edges[id].u);
            }
        }
        return level[t] != -1;
    }

    long long dfs(int v, long long pushed) {
        if (pushed == 0)
            return 0;
        if (v == t)
            return pushed;
        for (int& cid = ptr[v]; cid < (int)adj[v].size(); cid++) {
            int id = adj[v][cid];
            int u = edges[id].u;
            if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1)
                continue;
            long long tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
            if (tr == 0)
                continue;
            edges[id].flow += tr;
            edges[id ^ 1].flow -= tr;
            return tr;
        }
        return 0;
    }

    long long flow() {
        long long f = 0;
        while (true) {
            fill(level.begin(), level.end(), -1);
            level[s] = 0;
            q.push(s);
            if (!bfs())
                break;
            fill(ptr.begin(), ptr.end(), 0);
            while (long long pushed = dfs(s, flow_inf)) {
                f += pushed;
            }
        }
        return f;
    }
};

int main() {
    int n, m, x;
    scanf("%d%d%d",&n,&m,&x);
    vector<piii> edges;
    while(m--) {
        int x, y, c;
        scanf("%d%d%d",&x,&y,&c);
        x--, y--;
        edges.pb({{x, y}, c});
    }
    double l = 0, r = 1e6;
    while(r-l>=EPS) {
        Dinic* dinic = new Dinic(n, 0, n-1);
        double mid = (l+r)/2;
        for(piii p : edges) {
            dinic->add_edge(p.f.f, p.f.s, p.s/mid+EPS);
        }
        int y = dinic->flow();
        if (y >= x) {
            l = mid;
        } else {
            r = mid;
        }
        delete dinic;
    }
    printf("%0.6f", l*x);
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 60;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
vector<unordered_map<long long, long long>> b ;
vector<unordered_map<long long, long long>> a = vector<unordered_map<long long, long long>> (M);
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (auto i: b[p]) {
        long long next = i.first;
        long long ca = i.second;
        long long ans = search(next, min(limit, ca - f[p][next] + f[next][p]));
        if (ans > 0) {
            int d = min(ca - f[p][next], ans);
            f[p][next] += d;
            f[next][p] -= (ans - d);
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
       // v = 0.4;
        b = vector<unordered_map<long long, long long>> (M);
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (auto j: a[i]) {
                b[i][j.first] = (long long) (j.second/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (auto j: b[i]) {
                printf("(%d %d)", j.first, j.second);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all <<"\n";
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 60;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
long long b[M][M] ;
long long a[M][M] ;
bool visited[M];
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (long long next = 2; next <= n; next ++) {
        long long ca = b[p][next];
        long long ans = search(next, min(limit, ca - f[p][next]));
        if (ans > 0) {
            f[p][next] += ans;
            f[next][p] -= ans;
            return ans;
        }
    }
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    memset(a,0,sizeof(a));
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.4;
        memset(b,0,sizeof(b));
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (long long j = 1; j <= n; j++) {
                b[i][j] = (long long) (a[i][j]/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (long long j = 1; j <= n; j++) {
                if (a[i][j] > 0)
                printf("(%d %d)", j, a[i][j]);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            memset(visited, 0, sizeof(visited));
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all <<"\n";
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        //break;
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 100;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
vector<map<long long, long long>> b ;
vector<map<long long, long long>> a = vector<map<long long, long long>> (M);
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (auto i: b[p]) {
        long long next = i.first;
        long long ca = i.second;
        long long ans = search(next, min(limit, ca - f[p][next] + b[next][p] - f[next][p]));
        if (ans > 0) {
            int d = min(ca - f[p][next], ans);
            f[p][next] += d;
            f[next][p] -= (ans - d);
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.476842;
        b = vector<map<long long, long long>> (M);
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (auto j: a[i]) {
                b[i][j.first] = (long long) (j.second/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (auto j: b[i]) {
                printf("(%d %d)", j.first, j.second);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all;
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 60;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
long long b[M][M] ;
long long a[M][M] ;
bool visited[M];
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (long long next = 2; next <= n; next ++) {
        long long ca = b[p][next];
        long long ans = search(next, min(limit, ca - f[p][next]));
        if (ans > 0) {
            f[p][next] += ans;
            f[next][p] -= ans;
            return ans;
        }
    }
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    memset(a,0,sizeof(a));
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    for (int r = 0; r < 200; r++){
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.4;
        memset(b,0,sizeof(b));
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (long long j = 1; j <= n; j++) {
                b[i][j] = (long long) (a[i][j]/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (long long j = 1; j <= n; j++) {
                if (a[i][j] > 0)
                printf("(%d %d)", j, a[i][j]);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            memset(visited, 0, sizeof(visited));
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all <<"\n";
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        //break;
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 60;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
vector<map<long long, long long>> b ;
vector<map<long long, long long>> a = vector<map<long long, long long>> (M);
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (auto i: b[p]) {
        long long next = i.first;
        long long ca = i.second;
        long long ans = search(next, min(limit, ca - f[p][next] + f[next][p]));
        if (ans > 0) {
            int d = min(ca - f[p][next], ans);
            f[p][next] += d;
            f[next][p] -= (ans - d);
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.476842;
        b = vector<map<long long, long long>> (M);
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (auto j: a[i]) {
                b[i][j.first] = (long long) (j.second/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (auto j: b[i]) {
                printf("(%d %d)", j.first, j.second);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all;
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 60;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
vector<unordered_map<long long, long long>> b ;
vector<unordered_map<long long, long long>> a = vector<unordered_map<long long, long long>> (M);
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (auto i: b[p]) {
        long long next = i.first;
        long long ca = i.second;
        long long ans = search(next, min(limit, ca - f[p][next]));
        if (ans > 0) {
            int d = min(ca - f[p][next], ans);
            f[p][next] += ans;
            f[next][p] -= ans;
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.4;
        b = vector<unordered_map<long long, long long>> (M);
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (auto j: a[i]) {
                b[i][j.first] = (long long) (j.second/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (auto j: b[i]) {
                printf("(%d %d)", j.first, j.second);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all <<"\n";
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        //break;
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 60;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
vector<unordered_map<long long, long long>> b ;
vector<unordered_map<long long, long long>> a = vector<unordered_map<long long, long long>> (M);
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (auto i: b[p]) {
        long long next = i.first;
        long long ca = i.second;
        long long ans = search(next, min(limit, ca - f[p][next] + f[next][p]));
        if (ans > 0) {
            int d = min(ca - f[p][next], ans);
            f[p][next] += d;
            f[next][p] -= (ans - d);
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.476842;
        b = vector<unordered_map<long long, long long>> (M);
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (auto j: a[i]) {
                b[i][j.first] = (long long) (j.second/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (auto j: b[i]) {
                printf("(%d %d)", j.first, j.second);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all;
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 60;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
long long b[M][M] ;
long long a[M][M] ;
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (long long next = 2; next <= n; next ++) {
        long long ca = b[p][next];
        long long ans = search(next, min(limit, ca - f[p][next]));
        if (ans > 0) {
            f[p][next] += ans;
            f[next][p] -= ans;
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    memset(a,0,sizeof(a));
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.4;
        memset(b,0,sizeof(b));
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (long long j = 1; j <= n; j++) {
                b[i][j] = (long long) (a[i][j]/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (long long j = 1; j <= n; j++) {
                if (a[i][j] > 0)
                printf("(%d %d)", j, a[i][j]);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all <<"\n";
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        //break;
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 100;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
vector<map<long long, long long>> b ;
vector<map<long long, long long>> a = vector<map<long long, long long>> (M);
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (auto i: b[p]) {
        long long next = i.first;
        long long ca = i.second;
        long long ans = search(next, min(limit, ca - f[p][next]));
        if (ans > 0) {
            f[p][next] += ans;
            f[next][p] -= ans;
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
        a[y][x] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.476842;
        b = vector<map<long long, long long>> (M);
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (auto j: a[i]) {
                b[i][j.first] = (long long) (j.second/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (auto j: b[i]) {
                printf("(%d %d)", j.first, j.second);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all;
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 100;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
vector<map<long long, long long>> b ;
vector<map<long long, long long>> a = vector<map<long long, long long>> (M);
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (auto i: b[p]) {
        long long next = i.first;
        long long ca = i.second;
        long long ans = search(next, min(limit, ca - f[p][next]));
        if (ans > 0) {
            f[p][next] += ans;
            f[next][p] -= ans;
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.476842;
        b = vector<map<long long, long long>> (M);
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (auto j: a[i]) {
                b[i][j.first] = (long long) (j.second/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (auto j: b[i]) {
                printf("(%d %d)", j.first, j.second);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all;
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


#include <bits/stdc++.h>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

// less_equal if supports multiple items
typedef tree<long long, null_type, less<long long>, rb_tree_tag,
             tree_order_statistics_node_update>
    dataSet;

const long long MOD = 1e9+7;
const long long M = 100;
const double eps = 0.0000001;
long long n, m, w, x, y, z;
vector<unordered_map<long long, long long>> b ;
vector<unordered_map<long long, long long>> a = vector<unordered_map<long long, long long>> (M);
vector<bool> visited = vector<bool>(M, false);
long long f[M][M];
long long search(long long p, long long limit) {
    if (limit == 0) return 0;
    if (visited[p]) return 0;
    if (p == n) return limit;
    visited[p] = true;
    for (auto i: b[p]) {
        long long next = i.first;
        long long ca = i.second;
        long long ans = search(next, min(limit, ca - f[p][next] + b[next][p] - f[next][p]));
        if (ans > 0) {
            int d = min(ca - f[p][next], ans);
            f[p][next] += d;
            f[next][p] -= (ans - d);
            visited[p] = false;
            return ans;
        }
    }
    visited[p] = false;
    return 0;
}
int main ( )
{
    cout << setprecision(15);
    scanf("%lld%lld%lld", &n, &m, &w);
    for (long long i = 0; i < m; i++) {
        scanf("%lld%lld%lld", &x, &y, &z);
        a[x][y] = z;
    }
    double low = 0, high =1000010;
    while (high - low > eps) {
        double v = (high + low)/2.0;
        //cout <<low << " "<< v <<" "<< high<<" +++\n";
        //v = 0.476842;
        b = vector<unordered_map<long long, long long>> (M);
        memset(f, 0, sizeof(f));
        for (long long i = 1; i <= n; i++) {
            for (auto j: a[i]) {
                b[i][j.first] = (long long) (j.second/v);
            }
        }
        /*
        for (long long i = 1; i <= n; i++) {
            cout << i <<": ";
            for (auto j: b[i]) {
                printf("(%d %d)", j.first, j.second);
            }
            printf("\n");
        }*/
        long long found = 1;
        while (found > 0) {
            found = search(1, numeric_limits<long long>::max());
            //printf("%d\n", found);
        }
        long long all = 0;
        for (long long i = 2; i <= n; i++) {
            all += f[1][i];
        }
        /*
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j++) {
                printf("%d ", f[i][j]);
            }
            printf("\n");
        }
        cout << all;
        cout <<low << " "<< v <<" "<< high<<" ---\n";

        printf("\n");
        printf("\n");*/
        if (all < w) {
            high = v;
        } else {
            low = v;
        }

    }
    cout << low * w;
    return 0;
}


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

typedef long long ll;
typedef pair<int, int> ii;

int MOD = 1e9 + 7;
int INF = 1e9;
// ll INF = 1e18;

struct edge{
    int from, to; ll cap;
    edge *rev;
    edge(int u, int v, ll c) : from(u), to(v), cap(c), rev(NULL) {}
};

int n, s, t;
int dist[55];
edge *p[55];
vector<edge*> g[55];

void addedge(int u, int v, ll c){
    edge *in = new edge(u, v, c);
    edge *out = new edge(v, u, 0);
    in->rev = out; out->rev = in;
    g[u].push_back(in); g[v].push_back(out);
}

ll maxflow(){
	ll mxf = 0;
	for(;;){
		for(int i=0;i<n;i++) p[i] = NULL;
        for(int i=0;i<n;i++) dist[i] = INF;
        queue<int> q; q.push(s); dist[s] = 0;
        while(!q.empty()){
            int u = q.front(); q.pop();
            if(u == t) break;
            for(edge *e: g[u]) {
                int v = e->to;
                if(e->cap > 0 && dist[v] == INF){
                    dist[v] = dist[u] + 1;
                    p[v] = e;
                    q.push(v);
                }
            }
        }
		if(dist[t] == INF) break;
		ll fo = INF;
        for(int u = t; p[u] != NULL; u = p[u]->from)
            fo = min(fo, p[u]->cap);
        for(int u = t; p[u] != NULL; u = p[u]->from)
            p[u]->cap -= fo, p[u]->rev->cap += fo;
		mxf += fo;
	}
	return mxf;
}

int m, x, u[505], v[505], w[505];

ll check(double d){
	for(int i=0;i<n;i++) g[i].clear();
	for(int i=0;i<m;i++){
		addedge(u[i], v[i], floor(w[i] / d));
	}
	return maxflow();
}

int solve(){
	cin >> n >> m >> x;
	s = 0, t = n-1;
	for(int i=0;i<m;i++){
		cin >> u[i] >> v[i] >> w[i]; u[i]--, v[i]--;
	}

	double lo = 0, hi = 1e9;
	for(int j=0;j<100;j++){
		double mi = (lo + hi) / 2;
		// cerr << mi << ' ' << check(mi) << endl;
		if(check(mi) < x)
			hi = mi;
		else
			lo = mi;
	}
	cout << fixed << setprecision(8) << lo * x << endl;
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	// int t; cin >> t; while(t--)
	solve();
	// cout << (solve() ? "YES" : "NO") << endl;
	return 0;
}


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

typedef long long ll;
typedef pair<int, int> ii;

int MOD = 1e9 + 7;
int INF = 1e9;
// ll INF = 1e18;

int n, s, t;
int p[55], dist[55];
ll cap[55][55];
vector<int> g[55];

void addedge(int u, int v, ll c){
	g[u].push_back(v); g[v].push_back(u);
	cap[u][v] = c; cap[v][u] = 0;
}

vector<ll> maxflow(){
	vector<ll> rt;
	for(;;){
		for(int i=0;i<n;i++) p[i] = -1;
		for(int i=0;i<n;i++) dist[i] = INF;
		queue<int> q; q.push(s); dist[s] = 0;
		while(!q.empty()){
			int u = q.front(); q.pop();
			if(u == t) break;
			for(int v: g[u]) if(cap[u][v] > 0 && dist[v] == INF){
				dist[v] = dist[u] + 1;
				p[v] = u;
				q.push(v);
			}
		}
		if(dist[t] == INF) break;
		ll fo = 1LL * INF * INF;
		for(int u = t; p[u] != -1; u = p[u])
			fo = min(fo, cap[p[u]][u]);
		for(int u = t; p[u] != -1; u = p[u])
			cap[p[u]][u] -= fo, cap[u][p[u]] += fo;
		rt.push_back(fo);
	}
	return rt;
}

int m, x;

int solve(){
	cin >> n >> m >> x;
	s = 0, t = n-1;
	while(m--){
		int u, v, w; cin >> u >> v >> w; u--, v--;
		addedge(u, v, w);
	}
	vector<ll> get = maxflow();
	double lo = 0, hi = 1e9;
	for(int j=0;j<60;j++){
		double mi = (lo + hi) / 2;
		ll cnt = 0;
		for(int i=0;i<get.size();i++) cnt += floor(get[i] / mi);
		if(cnt < x)
			hi = mi;
		else
			lo = mi;
	}
	cout << fixed << setprecision(8) << lo * x << endl;
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	// int t; cin >> t; while(t--)
	solve();
	// cout << (solve() ? "YES" : "NO") << endl;
	return 0;
}


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

typedef long long ll;
typedef pair<int, int> ii;

int MOD = 1e9 + 7;
int INF = 1e9;
// ll INF = 1e18;

struct edge{
    int from, to; ll cap;
    edge *rev;
    edge(int u, int v, int c) : from(u), to(v), cap(c), rev(NULL) {}
};

int n, s, t;
int dist[55];
edge *p[55];
vector<edge*> g[55];

void addedge(int u, int v, int c){
    edge *in = new edge(u, v, c);
    edge *out = new edge(v, u, 0);
    in->rev = out; out->rev = in;
    g[u].push_back(in); g[v].push_back(out);
}

vector<ll> maxflow(){
	vector<ll> rt;
	for(;;){
		for(int i=0;i<n;i++) p[i] = NULL;
        for(int i=0;i<n;i++) dist[i] = INF;
        queue<int> q; q.push(s); dist[s] = 0;
        while(!q.empty()){
            int u = q.front(); q.pop();
            if(u == t) break;
            for(edge *e: g[u]) {
                int v = e->to;
                if(e->cap > 0 && dist[v] == INF){
                    dist[v] = dist[u] + 1;
                    p[v] = e;
                    q.push(v);
                }
            }
        }
		if(dist[t] == INF) break;
		ll fo = INF;
        for(int u = t; p[u] != NULL; u = p[u]->from)
            fo = min(fo, p[u]->cap);
        for(int u = t; p[u] != NULL; u = p[u]->from)
            p[u]->cap -= fo, p[u]->rev->cap += fo;
		rt.push_back(fo);
	}
	return rt;
}

int m, x;

int solve(){
	cin >> n >> m >> x;
	s = 0, t = n-1;
	while(m--){
		int u, v, w; cin >> u >> v >> w; u--, v--;
		addedge(u, v, w);
	}
	vector<ll> get = maxflow();
	double lo = 0, hi = 1e9;
	for(int j=0;j<100;j++){
		double mi = (lo + hi) / 2;
		ll cnt = 0;
		for(int i=0;i<get.size();i++) cnt += floor(get[i] / mi);
		if(cnt < x)
			hi = mi;
		else
			lo = mi;
	}
	cout << fixed << setprecision(8) << lo * x << endl;
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	// int t; cin >> t; while(t--)
	solve();
	// cout << (solve() ? "YES" : "NO") << endl;
	return 0;
}


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

typedef long long ll;
typedef pair<int, int> ii;

int MOD = 1e9 + 7;
int INF = 1e9;
// ll INF = 1e18;

struct edge{
    int from, to; ll cap;
    edge *rev;
    edge(int u, int v, int c) : from(u), to(v), cap(c), rev(NULL) {}
};

int n, s, t;
int dist[55];
edge *p[55];
vector<edge*> g[55];

void addedge(int u, int v, int c){
    edge *in = new edge(u, v, c);
    edge *out = new edge(v, u, 0);
    in->rev = out; out->rev = in;
    g[u].push_back(in); g[v].push_back(out);
}

vector<ll> maxflow(){
	vector<ll> rt;
	for(;;){
		for(int i=0;i<n;i++) p[i] = NULL;
        for(int i=0;i<n;i++) dist[i] = INF;
        queue<int> q; q.push(s); dist[s] = 0;
        while(!q.empty()){
            int u = q.front(); q.pop();
            if(u == t) break;
            for(edge *e: g[u]) {
                int v = e->to;
                if(e->cap > 0 && dist[v] == INF){
                    dist[v] = dist[u] + 1;
                    p[v] = e;
                    q.push(v);
                }
            }
        }
		if(dist[t] == INF) break;
		ll fo = INF;
        for(int u = t; p[u] != NULL; u = p[u]->from)
            fo = min(fo, p[u]->cap);
        for(int u = t; p[u] != NULL; u = p[u]->from)
            p[u]->cap -= fo, p[u]->rev->cap += fo;
		rt.push_back(fo);
	}
	return rt;
}

int m, x;

int solve(){
	cin >> n >> m >> x;
	s = 0, t = n-1;
	while(m--){
		int u, v, w; cin >> u >> v >> w; u--, v--;
		addedge(u, v, w);
	}
	vector<ll> get = maxflow();
	double lo = 0, hi = 1e9;
	for(int j=0;j<60;j++){
		double mi = (lo + hi) / 2;
		ll cnt = 0;
		for(int i=0;i<get.size();i++) cnt += floor(get[i] / mi);
		if(cnt < x)
			hi = mi;
		else
			lo = mi;
	}
	cout << fixed << setprecision(8) << lo * x << endl;
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	// int t; cin >> t; while(t--)
	solve();
	// cout << (solve() ? "YES" : "NO") << endl;
	return 0;
}


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

typedef long long ll;
typedef pair<int, int> ii;

int MOD = 1e9 + 7;
int INF = 1e9;
// ll INF = 1e18;

struct edge{
    int from, to; ll cap;
    edge *rev;
    edge(int u, int v, int c) : from(u), to(v), cap(c), rev(NULL) {}
};

int n, s, t;
int dist[55];
edge *p[55];
vector<edge*> g[55];

void addedge(int u, int v, int c){
    edge *in = new edge(u, v, c);
    edge *out = new edge(v, u, 0);
    in->rev = out; out->rev = in;
    g[u].push_back(in); g[v].push_back(out);
}

ll maxflow(){
	ll mxf = 0;
	for(;;){
		for(int i=0;i<n;i++) p[i] = NULL;
        for(int i=0;i<n;i++) dist[i] = INF;
        queue<int> q; q.push(s); dist[s] = 0;
        while(!q.empty()){
            int u = q.front(); q.pop();
            if(u == t) break;
            for(edge *e: g[u]) {
                int v = e->to;
                if(e->cap > 0 && dist[v] == INF){
                    dist[v] = dist[u] + 1;
                    p[v] = e;
                    q.push(v);
                }
            }
        }
		if(dist[t] == INF) break;
		ll fo = INF;
        for(int u = t; p[u] != NULL; u = p[u]->from)
            fo = min(fo, p[u]->cap);
        for(int u = t; p[u] != NULL; u = p[u]->from)
            p[u]->cap -= fo, p[u]->rev->cap += fo;
		mxf += fo;
	}
	return mxf;
}

int m, x, u[505], v[505], w[505];

ll check(double d){
	for(int i=0;i<n;i++) g[i].clear();
	for(int i=0;i<m;i++){
		addedge(u[i], v[i], floor(w[i] / d));
	}
	return maxflow();
}

int solve(){
	cin >> n >> m >> x;
	s = 0, t = n-1;
	for(int i=0;i<m;i++){
		cin >> u[i] >> v[i] >> w[i]; u[i]--, v[i]--;
	}

	double lo = 0, hi = 1e9;
	for(int j=0;j<100;j++){
		double mi = (lo + hi) / 2;
		if(check(mi) < x)
			hi = mi;
		else
			lo = mi;
	}
	cout << fixed << setprecision(8) << lo * x << endl;
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	// int t; cin >> t; while(t--)
	solve();
	// cout << (solve() ? "YES" : "NO") << endl;
	return 0;
}


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

typedef long long ll;
typedef pair<int, int> ii;

int MOD = 1e9 + 7;
int INF = 1e9;
// ll INF = 1e18;

int n, s, t;
int p[55], dist[55];
ll cap[55][55];
vector<int> g[55];

void addedge(int u, int v, ll c){
	g[u].push_back(v); g[v].push_back(u);
	cap[u][v] = c; cap[v][u] = 0;
}

vector<ll> maxflow(){
	vector<ll> rt;
	for(;;){
		for(int i=0;i<n;i++) p[i] = -1;
		for(int i=0;i<n;i++) dist[i] = INF;
		queue<int> q; q.push(s); dist[s] = 0;
		while(!q.empty()){
			int u = q.front(); q.pop();
			if(u == t) break;
			for(int v: g[u]) if(cap[u][v] > 0 && dist[v] == INF){
				dist[v] = dist[u] + 1;
				p[v] = u;
				q.push(v);
			}
		}
		if(dist[t] == INF) break;
		ll fo = 1LL * INF * INF;
		for(int u = t; p[u] != -1; u = p[u])
			fo = min(fo, cap[p[u]][u]);
		for(int u = t; p[u] != -1; u = p[u])
			cap[p[u]][u] -= fo, cap[u][p[u]] += fo;
		rt.push_back(fo);
	}
	return rt;
}

int m, x;

int solve(){
	cin >> n >> m >> x;
	s = 0, t = n-1;
	while(m--){
		int u, v, w; cin >> u >> v >> w; u--, v--;
		addedge(u, v, w);
	}
	vector<ll> get = maxflow();
	for(int i=0;i<get.size();i++) cout << get[i] << endl;
	double lo = 0, hi = 1e9;
	for(int j=0;j<60;j++){
		double mi = (lo + hi) / 2;
		ll cnt = 0;
		for(int i=0;i<get.size();i++) cnt += floor(get[i] / mi);
		if(cnt < x)
			hi = mi;
		else
			lo = mi;
	}
	cout << fixed << setprecision(8) << lo * x << endl;
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	// int t; cin >> t; while(t--)
	solve();
	// cout << (solve() ? "YES" : "NO") << endl;
	return 0;
}


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

typedef long long ll;
typedef pair<int, int> ii;

int MOD = 1e9 + 7;
int INF = 1e9;
// ll INF = 1e18;

struct edge{
    int from, to; ll cap;
    edge *rev;
    edge(int u, int v, ll c) : from(u), to(v), cap(c), rev(NULL) {}
};

int n, s, t;
int dist[55], vis[55];
vector<edge*> g[55];

void addedge(int u, int v, ll c){
    edge *in = new edge(u, v, c);
    edge *out = new edge(v, u, 0);
    in->rev = out; out->rev = in;
    g[u].push_back(in); g[v].push_back(out);
}

ll dfs(int u, ll fo){
    if(u == t) return fo;
    for(;vis[u]<g[u].size();vis[u]++){
        edge *e = g[u][vis[u]];
        int v = e->to;
        if(dist[v] != dist[u] + 1 || e->cap <= 0) continue;
        ll foo = dfs(v, min(fo, e->cap));
        if(foo > 0) {
            e->cap -= foo;
            e->rev->cap += foo;
            return foo;
        }
    }
    return 0;
}

ll maxflow(){
    ll mxf = 0;
    for(;;){
        for(int i=0;i<n;i++) dist[i] = INF, vis[i] = 0;
        queue<int> q; q.push(s); dist[s] = 0;
        while(!q.empty()){
            int u = q.front(); q.pop();
            if(u == t) break;
            for(edge *e: g[u]){
                int v = e->to;
                if(e->cap > 0 && dist[v] == INF){
                    dist[v] = dist[u] + 1;
                    q.push(v);
                }
            }
        }
        if(dist[t] == INF) break;
        while(ll fo = dfs(s, 1LL * INF * INF))
            mxf += fo;
    }
    return mxf;
}

int m, x, u[505], v[505], w[505];

ll check(double d){
	for(int i=0;i<n;i++) g[i].clear();
	for(int i=0;i<m;i++){
		addedge(u[i], v[i], floor(w[i] / d));
	}
	return maxflow();
}

int solve(){
	cin >> n >> m >> x;
	s = 0, t = n-1;
	for(int i=0;i<m;i++){
		cin >> u[i] >> v[i] >> w[i]; u[i]--, v[i]--;
	}

	double lo = 0, hi = 1e9;
	for(int j=0;j<100;j++){
		double mi = (lo + hi) / 2;
		if(check(mi) < x)
			hi = mi;
		else
			lo = mi;
	}
	cout << fixed << setprecision(8) << lo * x << endl;
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	// int t; cin >> t; while(t--)
	solve();
	// cout << (solve() ? "YES" : "NO") << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

//<editor-fold desc="debugger">

template <class X, class Y>
ostream & operator << (ostream & os, const pair <X, Y>& p) {
    return os << "[" << p.first << ", " << p.second << "]" ;
}

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, const Container& x) {
    os << "{";
    bool f = 1;
    for (auto&y : x) {
        if (!f) os << ", ";
        else f = 0;
        os << y;
    }
    return os << "}";
}

struct Debug {
#ifndef ONLINE_JUDGE
    template<class T>
    Debug& operator << (const T& x) {
        cerr << x << " , ";
        return *this;
    }
    ~Debug() {cerr << endl;}
#define debug cerr << "Line(" << __LINE__ << ") : " , Debug()
#else
    template<class T>
    Debug& operator << (const T& x) {
        return *this;
    }
    #define debug Debug()
#endif
};

//</editor-fold>

//  (EV * min(flow , V))
// (EsqrtV) on bibrtite graphs

struct edge {
    int to , cap;
};

const int N = 55; // make sure is greater than max_node will ever be
int dist[N] , p[N] , src , max_node , snk; // don't forget to set src and snk
vector<edge> edges;
vector<int> network[N]; // adjacency list for maxflow

void addAugEdge(int u , int v , int c) {
    max_node = max(max_node , max(u , v));
    network[u].push_back(edges.size());
    edges.push_back({v , c});
    network[v].push_back(edges.size());
    edges.push_back({u , 0}); // c if undirected 0 if directed
}

bool BFS() {
    memset(dist , -1 , (max_node + 1) * sizeof dist[0]);
    queue<int> q;
    q.push(src);
    dist[src] = 0;

    while (q.size()) {
        int cur = q.front();
        q.pop();
        for (int ci : network[cur]) {
            auto &e = edges[ci];
            if (dist[e.to] == -1 && e.cap) {
                q.push(e.to);
                dist[e.to] = dist[cur] + 1;
            }
        }
    }

    return max_node >= snk && dist[snk] != -1;
}

int DFS(int node , int flow) {
    if (node == snk || !flow)
        return flow;

    for (; p[node] < network[node].size() ; p[node]++) {
        auto &e= edges[network[node][p[node]]];
        auto &re = edges[network[node][p[node]]^1];

        if (dist[node] + 1  != dist[e.to]) continue;

        int push = DFS(e.to , min(flow , e.cap));
        if (push) {
            e.cap -= push;
            re.cap += push;
            return push;
        }
    }

    return 0;
}

long long dinic() {
    long long flow = 0;
    while (BFS()) {
        memset(p , 0 , sizeof p);
        while (int f = DFS(src , 1e9)) // make sure that no edge has cap greater than 1e9
            flow += f;
    }
    return flow;
}

void init() { // every test case
    edges.clear();
    for (int i = 0 ;i <= max_node;i++)
        network[i].clear();
    max_node = 0;
}

vector<array<int , 3> > edgeList;
bool can(double v , int need) {
    init();
    for (auto &e : edgeList)
        addAugEdge(e[0] , e[1] , e[2] / v);
    return dinic() >= need;
}

int main() {
    ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in" , "r" , stdin);
#endif
    int n , m , x;
    cin >> n >> m >> x;

    while (m--) {
        int u , v , c;
        cin >> u >> v >> c;
        edgeList.push_back({u , v , c});
    }

    src = 1 , snk = n;

    double l = 0 , r = 1e6 + 6 , ans = -1;
    for (int it = 0 ; it < 200 ; it++) {
        double mid = (l + r) / 2;
        if (can(mid , x)) {
            ans = mid;
            l = mid;
        } else {
            r = mid;
        }
    }

    cout << fixed << setprecision(12) << ans * x;
}