#include<bits/stdc++.h>
using namespace std;
#define FasterIO ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
typedef long long     ll;
typedef pair<int,int> pi;
#define ff first
#define ss second

const int MX=100000;
const int inf=1e9;

struct DinicMaxflow
{
    struct edge
    {
        int a, b, cap, flow ;
        edge(int _a, int _b, int _c, int _d)
        {
            a = _a, b = _b, cap = _c, flow = _d;
        }
    } ;

    int n, s, t, level [ MX ], ptr [ MX ] ;
    vector < edge > e ;
    vector < int > g [ MX ] ;
    queue<int>q;

    void add_edge ( int a, int b, int cap )
    {
        edge e1 = edge( a, b, cap, 0 ) ;
        edge e2 = edge( b, a, 0, 0 ) ;
        g [ a ] . push_back ( ( int ) e. size ( ) ) ;
        e. push_back ( e1 ) ;
        g [ b ] . push_back ( ( int ) e. size ( ) ) ;
        e. push_back ( e2 ) ;
    }
    bool bfs ( )
    {
        memset ( level, -1, sizeof level ) ;
        level [ s ] = 0 ;
        q.push(s);
        while( !q.empty() )
        {
            int u = q.front();
            q.pop();
            for(int i=0; i<g[u].size(); i++)
            {
                int id = g[u][i];
                int v = e[id].b;
                if ( level [ v ] == - 1 && e [ id ] . flow < e [ id ] . cap )
                {
                    level[v] = level[u]+1;
                    q.push(v);
                }
            }
        }
        return level [ t ] != - 1 ;
    }
    int dfs ( int u, int flow )
    {
        if ( ! flow )  return 0 ;
        if ( u == t )  return flow ;
        for ( ; ptr [ u ] < ( int ) g [ u ] . size ( ) ; ++ ptr [ u ] )
        {
            int id = g [ u ] [ ptr [ u ] ] ;
            int v = e [ id ] . b ;
            if ( level [ v ] != level [ u ] + 1 )  continue ;
            int mxflow = dfs ( v, min ( flow, e [ id ] . cap - e [ id ] . flow ) ) ;
            if ( mxflow )
            {
                e [ id ] . flow += mxflow ;
                e [ id ^ 1 ] . flow -= mxflow ;
                return mxflow ;
            }
        }
        return 0 ;
    }
    int MaxFlow ( )
    {
        int flow = 0 ;
        while(bfs())
        {
            memset ( ptr, 0, sizeof ptr ) ;
            while ( int mxflow = dfs ( s, inf ) )
            {
                flow += mxflow ;
                if(mxflow == 0)break;
            }
        }
        return flow ;
    }

    void init( int _n, int _s, int _t )
    {
        n = _n;
        s = _s;
        t = _t;
        for(int i=0; i<e.size(); i++) e[i].flow=0;
    }
    void RESET()
    {
        e.clear();
        for(int i=0; i<=n; i++) g[i].clear();
    }
} DMF;

vector<pair<int, pi> >ed;

int main()
{
    FasterIO;
    int n, m, x;
    cin>>n>>m>>x;
    for(int i=1; i<=m; i++)
    {
        int a, b, cap;
        cin>>a>>b>>cap;
        ed.push_back({cap, {a, b}});
    }
    double lo=0, hi=100000, md, res=0;
    for(int i=0; i<=200; i++)
    {
        md=(lo+hi)/2.0;
        DMF.RESET();
        DMF.init(n,1,n);
        for(int i=0; i<m; i++)
        {
            DMF.add_edge(ed[i].ss.ff, ed[i].ss.ss, (1.0*ed[i].ff)/md);
        }
        int ans=DMF.MaxFlow();
        if(ans>=x)
        {
            res=md; lo=md;
        }
        else hi=md;
    }
    cout<<setprecision(10)<<fixed<<(x*1.0*res)<<endl;
    return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
using namespace std;
const int max_n=55;
const int inf=1e8;
const double Diff=1e-7;
int iter[max_n];
int level[max_n];
struct Edge{
    int to,cap,rev;
};
vector<Edge> G[max_n];
void Add(int from,int to,int cap){
    G[from].push_back((Edge){to,cap,(int)G[to].size()});
    G[to].push_back((Edge){from,0,(int)G[from].size()-1});
}
int dfs(int v,int t,int f){
    if(v==t)
        return f;
    for(int &i=iter[v];i<G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0 &&level[e.to]>level[v]){
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
bool bfs(int s,int t){
    memset(level,-1,sizeof(level));
    level[s]=0;
    queue<int> que;
    que.push(s);
    while(!que.empty()){
        int p=que.front();
        que.pop();
        for(Edge &e:G[p]){
            if(level[e.to]<0 &&e.cap>0){
                level[e.to]=level[p]+1;
                que.push(e.to);
            }
        }
    }
    return level[t]>0;
}
int Dinic(int s,int t){
    int flow=0;
    while(bfs(s,t)){
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,inf))>0){
            flow+=f;
        }
    }
    return flow;
}
int n,m,x;
struct E{
    int from,to,cap;
};
vector<E> Graph;
bool solve(double f){
    for(int i=1;i<max_n;i++){
        G[i].clear();
    }
    double bear=f/x;
    for(E e:Graph){
        Add(e.from,e.to,(double)(e.cap)/bear);
    }
    return Dinic(1,n)>=x;
}
int main(){
    scanf("%d%d%d",&n,&m,&x);
    for(int i=1;i<=m;i++){
        int u,v,cap;
        scanf("%d%d%d",&u,&v,&cap);
        Graph.push_back({u,v,cap});
    }
    double lo=0,hi=inf;
    while(lo<hi-Diff){
        double mid=(lo+hi)/2;
        if(solve(mid))
            lo=mid;
        else
            hi=mid;
    }
    cout<<fixed<<setprecision(15)<<hi;
    return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
using namespace std;
typedef long long ll;
const int max_n=55;
const int inf=1e8;
const double Diff=1e-7;
int iter[max_n];
int level[max_n];
struct Edge{
    int to,cap,rev;
};
vector<Edge> G[max_n];
void Add(int from,int to,int cap){
    G[from].push_back((Edge){to,cap,(int)G[to].size()});
    G[to].push_back((Edge){from,0,(int)G[from].size()-1});
}
int dfs(int v,int t,int f){
    if(v==t)
        return f;
    for(int &i=iter[v];i<G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0 &&level[e.to]>level[v]){
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
bool bfs(int s,int t){
    memset(level,-1,sizeof(level));
    level[s]=0;
    queue<int> que;
    que.push(s);
    while(!que.empty()){
        int p=que.front();
        que.pop();
        for(Edge &e:G[p]){
            if(level[e.to]<0 &&e.cap>0){
                level[e.to]=level[p]+1;
                que.push(e.to);
            }
        }
    }
    return level[t]>0;
}
int Dinic(int s,int t){
    int flow=0;
    while(bfs(s,t)){
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,inf))>0){
            flow+=f;
        }
    }
    return flow;
}
int n,m,x;
struct E{
    int from,to,cap;
};
vector<E> Graph;
bool solve(double f){
    for(int i=1;i<max_n;i++){
        G[i].clear();
    }
    for(E e:Graph){
        Add(e.from,e.to,(double)((ll)(e.cap*x))/f);
    }
    return Dinic(1,n)>=x;
}
int main(){
    scanf("%d%d%d",&n,&m,&x);
    for(int i=1;i<=m;i++){
        int u,v,cap;
        scanf("%d%d%d",&u,&v,&cap);
        Graph.push_back({u,v,cap});
    }
    double lo=0,hi=inf;
    while(lo<hi-Diff){
        double mid=(lo+hi)/2;
        if(solve(mid))
            lo=mid;
        else
            hi=mid;
    }
    cout<<fixed<<setprecision(15)<<hi;
    return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
using namespace std;
const int max_n=55;
const int inf=1e8;
const double Diff=1e-9;
int iter[max_n];
int level[max_n];
struct Edge{
    int to,cap,rev;
};
vector<Edge> G[max_n];
void Add(int from,int to,int cap){
    G[from].push_back((Edge){to,cap,(int)G[to].size()});
    G[to].push_back((Edge){from,0,(int)G[from].size()-1});
}
int dfs(int v,int t,int f){
    if(v==t)
        return f;
    for(int &i=iter[v];i<G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0 &&level[e.to]>level[v]){
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
bool bfs(int s,int t){
    memset(level,-1,sizeof(level));
    level[s]=0;
    queue<int> que;
    que.push(s);
    while(!que.empty()){
        int p=que.front();
        que.pop();
        for(Edge &e:G[p]){
            if(level[e.to]<0 &&e.cap>0){
                level[e.to]=level[p]+1;
                que.push(e.to);
            }
        }
    }
    return level[t]>0;
}
int Dinic(int s,int t){
    int flow=0;
    while(bfs(s,t)){
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,inf))>0){
            flow+=f;
        }
    }
    return flow;
}
int n,m,x;
struct E{
    int from,to,cap;
};
vector<E> Graph;
bool solve(double f){
    for(int i=1;i<max_n;i++){
        G[i].clear();
    }
    double bear=f/x;
    for(E e:Graph){
        Add(e.from,e.to,(double)(e.cap)/bear);
    }
    return Dinic(1,n)>=x;
}
int main(){
    scanf("%d%d%d",&n,&m,&x);
    for(int i=1;i<=m;i++){
        int u,v,cap;
        scanf("%d%d%d",&u,&v,&cap);
        Graph.push_back({u,v,cap});
    }
    double lo=0,hi=inf;
    while(lo<hi-Diff){
        double mid=(lo+hi)/2;
        if(solve(mid))
            lo=mid;
        else
            hi=mid;
    }
    cout<<fixed<<setprecision(15)<<hi;
    return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
using namespace std;
typedef long long ll;
const int max_n=55;
const int inf=1e8;
const double Diff=1e-7;
int iter[max_n];
int level[max_n];
struct Edge{
    int to;
    ll cap;
    int rev;
};
vector<Edge> G[max_n];
void Add(int from,int to,ll cap){
    G[from].push_back((Edge){to,cap,(int)G[to].size()});
    G[to].push_back((Edge){from,0,(int)G[from].size()-1});
}
ll dfs(int v,int t,ll f){
    if(v==t)
        return f;
    for(int &i=iter[v];i<G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0 &&level[e.to]>level[v]){
            ll d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
bool bfs(int s,int t){
    memset(level,-1,sizeof(level));
    level[s]=0;
    queue<int> que;
    que.push(s);
    while(!que.empty()){
        int p=que.front();
        que.pop();
        for(Edge &e:G[p]){
            if(level[e.to]<0 &&e.cap>0){
                level[e.to]=level[p]+1;
                que.push(e.to);
            }
        }
    }
    return level[t]>0;
}
ll Dinic(int s,int t){
    ll flow=0;
    while(bfs(s,t)){
        memset(iter,0,sizeof(iter));
        ll f;
        while((f=dfs(s,t,inf))>0){
            flow+=f;
        }
    }
    return flow;
}
int n,m,x;
struct E{
    int from,to,cap;
};
vector<E> Graph;
bool solve(double f){
    for(int i=1;i<max_n;i++){
        G[i].clear();
    }
    for(E e:Graph){
        Add(e.from,e.to,(double)(e.cap*x)/f);
    }
    return Dinic(1,n)>=x;
}
int main(){
    scanf("%d%d%d",&n,&m,&x);
    for(int i=1;i<=m;i++){
        int u,v,cap;
        scanf("%d%d%d",&u,&v,&cap);
        Graph.push_back({u,v,cap});
    }
    double lo=0,hi=inf;
    while(lo<hi-Diff){
        double mid=(lo+hi)/2;
        if(solve(mid))
            lo=mid;
        else
            hi=mid;
    }
    cout<<fixed<<setprecision(15)<<hi;
    return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
using namespace std;
const int max_n=55;
const int inf=1e8;
const double Diff=1e-9;
int iter[max_n];
int level[max_n];
struct Edge{
    int to,cap,rev;
};
vector<Edge> G[max_n];
void Add(int from,int to,int cap){
    G[from].push_back((Edge){to,cap,(int)G[to].size()});
    G[to].push_back((Edge){from,0,(int)G[from].size()-1});
}
int dfs(int v,int t,int f){
    if(v==t)
        return f;
    for(int &i=iter[v];i<G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0 &&level[e.to]>level[v]){
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
bool bfs(int s,int t){
    memset(level,-1,sizeof(level));
    level[s]=0;
    queue<int> que;
    que.push(s);
    while(!que.empty()){
        int p=que.front();
        que.pop();
        for(Edge &e:G[p]){
            if(level[e.to]<0 &&e.cap>0){
                level[e.to]=level[p]+1;
                que.push(e.to);
            }
        }
    }
    return level[t]>0;
}
int Dinic(int s,int t){
    int flow=0;
    while(bfs(s,t)){
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,inf))>0){
            flow+=f;
        }
    }
    return flow;
}
int n,m,x;
struct E{
    int from,to,cap;
};
vector<E> Graph;
bool solve(double f){
    for(int i=1;i<max_n;i++){
        G[i].clear();
    }
    for(E e:Graph){
        Add(e.from,e.to,(double)(e.cap*x)/f);
    }
    return Dinic(1,n)>=x;
}
int main(){
    scanf("%d%d%d",&n,&m,&x);
    for(int i=1;i<=m;i++){
        int u,v,cap;
        scanf("%d%d%d",&u,&v,&cap);
        Graph.push_back({u,v,cap});
    }
    double lo=0,hi=inf;
    while(lo<hi-Diff){
        double mid=(lo+hi)/2;
        if(solve(mid))
            lo=mid;
        else
            hi=mid;
    }
    cout<<fixed<<setprecision(15)<<hi;
    return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<iomanip>
using namespace std;
typedef long long ll;
const int max_n=55;
const int inf=1e8;
const double Diff=1e-7;
int iter[max_n];
int level[max_n];
struct Edge{
    int to;
    ll cap;
    int rev;
};
vector<Edge> G[max_n];
void Add(int from,int to,ll cap){
    G[from].push_back((Edge){to,cap,(int)G[to].size()});
    G[to].push_back((Edge){from,0,(int)G[from].size()-1});
}
ll dfs(int v,int t,ll f){
    if(v==t)
        return f;
    for(int &i=iter[v];i<G[v].size();i++){
        Edge &e=G[v][i];
        if(e.cap>0 &&level[e.to]>level[v]){
            ll d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
bool bfs(int s,int t){
    memset(level,-1,sizeof(level));
    level[s]=0;
    queue<int> que;
    que.push(s);
    while(!que.empty()){
        int p=que.front();
        que.pop();
        for(Edge &e:G[p]){
            if(level[e.to]<0 &&e.cap>0){
                level[e.to]=level[p]+1;
                que.push(e.to);
            }
        }
    }
    return level[t]>0;
}
ll Dinic(int s,int t){
    ll flow=0;
    while(bfs(s,t)){
        memset(iter,0,sizeof(iter));
        ll f;
        while((f=dfs(s,t,inf))>0){
            flow+=f;
        }
    }
    return flow;
}
ll n,m,x;
struct E{
    int from,to,cap;
};
vector<E> Graph;
bool solve(double f){
    for(int i=1;i<max_n;i++){
        G[i].clear();
    }
    for(E e:Graph){
        Add(e.from,e.to,(double)(e.cap*x)/f);
    }
    return Dinic(1,n)>=x;
}
int main(){
    scanf("%d%d%d",&n,&m,&x);
    for(int i=1;i<=m;i++){
        int u,v,cap;
        scanf("%d%d%d",&u,&v,&cap);
        Graph.push_back({u,v,cap});
    }
    double lo=0,hi=inf;
    while(lo<hi-Diff){
        double mid=(lo+hi)/2;
        if(solve(mid))
            lo=mid;
        else
            hi=mid;
    }
    cout<<fixed<<setprecision(15)<<hi;
    return 0;
}


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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-7 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], int( min( 1.0 * din.INF, 1.0 * C[ i ] / mid ) ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-12 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
#pragma GCC optimize ("fast-math")

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

template< class T >
struct Dinic {
  static const int MAXV = 50;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-9 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-7 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      assert( typeid( C[ i ] / mid ) == typeid( 0 ) );
      din.add_edge( A[ i ], B[ i ], C[ i ] / mid );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


#pragma GCC optimize("O3")
#pragma GCC target("avx")

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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-13 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-7 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( din.INF, int( C[ i ] / mid ) ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-11 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-10 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
#pragma GCC optimize ("fast-math")

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

template< class T >
struct Dinic {
  static const int MAXV = 50;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  for( int i = 0; i < 100; ++i ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-13 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


#pragma GCC optimize("O3")
#pragma GCC target("avx")

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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-10 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
#pragma GCC optimize ("fast-math")

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

template< class T >
struct Dinic {
  static const int MAXV = 50;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-10 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-7 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      // assert( typeid( C[ i ] / mid ) == typeid( 0 ) );
      din.add_edge( A[ i ], B[ i ], C[ i ] / mid );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
#pragma GCC optimize ("fast-math")

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

template< class T >
struct Dinic {
  static const int MAXV = 10000;
  static const T INF = 0x3f3f3f3f;
  struct Edge {
    int v;
    T f;
    int re;
    Edge( int _v, T _f, int _re ): v( _v ), f( _f ), re( _re ) {}
  };
  int n, s, t, level[ MAXV ];
  vector< Edge > E[ MAXV ];
  int now[ MAXV ];
  Dinic( int _n, int _s, int _t ): n( _n ), s( _s ), t( _t ) {}
  void add_edge( int u, int v, T f, bool bidirectional = false ) {
    E[ u ].emplace_back( v, f, E[ v ].size() );
    E[ v ].emplace_back( u, 0, E[ u ].size() - 1 );
    if( bidirectional ) {
      E[ v ].emplace_back( u, f, E[ u ].size() - 1 );
    }
  }
  bool BFS() {
    memset( level, -1, sizeof( level ) );
    queue< int > que;
    que.emplace( s );
    level[ s ] = 0;
    while( not que.empty() ) {
      int u = que.front();
      que.pop();
      for( auto it: E[ u ] ) {
        if( it.f > 0 and level[ it.v ] == -1 ) {
          level[ it.v ] = level[ u ] + 1;
          que.emplace( it.v );
        }
      }
    }
    return level[ t ] != -1;
  }
  T DFS( int u, T nf ) {
    if( u == t ) return nf;
    T res = 0;
    while( now[ u ] < E[ u ].size() ) {
      Edge &it = E[ u ][ now[ u ] ];
      if( it.f > 0 and level[ it.v ] == level[ u ] + 1 ) {
        T tf = DFS( it.v, min( nf, it.f ) );
        res += tf; nf -= tf; it.f -= tf;
        E[ it.v ][ it.re ].f += tf;
        if( nf == 0 ) return res;
      } else ++now[ u ];
    }
    if( not res ) level[ u ] = -1;
    return res;
  }
  T flow( T res = 0 ) {
    while( BFS() ) {
      T temp;
      memset( now, 0, sizeof( now ) );
      while( temp = DFS( s, INF ) ) {
        res += temp;
        res = min( res, INF );
      }
    }
    return res;
  }
};

const int MAXN = 50;
const int MAXM = 500;

int N, M, X;
int A[ MAXM ], B[ MAXM ], C[ MAXM ];

signed main() {
  ios::sync_with_stdio( 0 );
  cin >> N >> M >> X;
  for( int i = 0; i < M; ++i ) {
    cin >> A[ i ] >> B[ i ] >> C[ i ];
    --A[ i ], --B[ i ];
  }
  double lb = 0.0, ub = 1e6;
  while( fabs( ub - lb ) > 1e-10 ) {
    double mid = ( lb + ub ) / 2;
    Dinic< int > din( N, 0, N - 1 );
    for( int i = 0; i < M; ++i ) {
      din.add_edge( A[ i ], B[ i ], min( C[ i ] / mid, 1e9 ) );
    }
    ( din.flow() >= X ? lb : ub ) = mid;
  }
  cout << fixed << setprecision( 7 ) << lb * X << endl;
  return 0;
}


/*
** Generic template
** avaicode 2017/2/19
** MIT License
*/

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

#define INF 2147480000
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SUM(x,y) accumulate(x,y,0)
#define gcd(x,y) (__gcd(x,y))
#define LOWBIT(x) (x&(-x))
#define CLR(x,y) memset(x,y,sizeof(x))
#define PD(x) printf("%d\n",(x))
#define PF(f) printf("%lf\n",(f))
#define PS(s) puts(s)
typedef long long LL;

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-')f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}

template<typename T>
struct Graph {
    enum { maxn = 55, maxm = 1005 };
    struct {
        int to, nxt;
        T w;
    } v[maxm];
    int h[maxn], cnt;
    Graph() { memset(h, -1, sizeof(h)); }
    void add(int x, int y, const T& w) {
        v[cnt].nxt = h[x];
        v[cnt].to = y; v[cnt].w = w;
        h[x] = cnt++;
    }
};
Graph<int> G;

queue<int> Q;
int f[55], cur[55];
double l, r, m1;
int n, m, x, y, z, k;
pair<pair<int, int>, int> v[505];

bool bfs() {
    Q.push(0);
    while (!Q.empty()) {
        int x = Q.front();
        for (int i = G.h[x]; i != -1; i = G.v[i].nxt) {
            int to = G.v[i].to;
            if (f[to] == 0 && G.v[i].w > 0) {
                f[to] = f[x] + 1;
                Q.push(to);
            }
        }
        Q.pop();
    }
    return f[n - 1] != 0;
}

int dfs(int x, int y) {
    if (y <= 0 || x == n - 1) return y;
    int t;
    for (int i = cur[x]; i != -1; i = G.v[i].nxt) {
        int to = G.v[i].to;
        if (f[to] != f[x] + 1) continue;
        t = dfs(to, min(G.v[i].w, y));

        if (t > 0) {
            G.v[i].w -= t; G.v[i ^ 1].w += t;
            cur[x] = i;
            return t;
        }
    }
    cur[x] = -1;
    return 0;
}

int dinic() {
    int ret = 0; memset(f, 0, sizeof(f)); f[0] = 1;
    while (bfs()) {
        int x = 0;
        for (int i = 0; i < n; ++i) cur[i] = G.h[i];
        while (x = dfs(0, INF))
            ret += x;
        memset(f, 0, sizeof(f)); f[0] = 1;
    }
    return ret;
}

int main(void) {
    n = read(); m = read(); k = read();
    for (int i = 0; i < m; ++i) {
        x = read() - 1; y = read() - 1; z = read();
        v[i] = mp(mp(x, y), z);
    }
    l = 0; r = 1000000.0;
    for (int i = 0; i < 200; ++i) {
        m1 = (l + r) / 2;
        memset(G.h, -1, sizeof(G.h));
        G.cnt = 0;
        for (int j = 0; j < m; ++j) {
            G.add(v[j].fi.fi, v[j].fi.se, (int)min((double)k, (double)v[j].se / m1));
            G.add(v[j].fi.se, v[j].fi.fi, 0);
        }
        if (dinic() < k) r = m1;
        else l = m1;
    }
    printf("%.10lf\n", l * k);
}


/*
** Generic template
** avaicode 2017/2/19
** MIT License
*/

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

#define INF 2147480000
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SUM(x,y) accumulate(x,y,0)
#define gcd(x,y) (__gcd(x,y))
#define LOWBIT(x) (x&(-x))
#define CLR(x,y) memset(x,y,sizeof(x))
#define PD(x) printf("%d\n",(x))
#define PF(f) printf("%lf\n",(f))
#define PS(s) puts(s)
typedef long long LL;

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-')f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}

template<typename T>
struct Graph {
    enum { maxn = 55, maxm = 1005 };
    struct {
        int to, nxt;
        T w;
    } v[maxm];
    int h[maxn], cnt;
    Graph() { memset(h, -1, sizeof(h)); }
    void add(int x, int y, const T& w) {
        v[cnt].nxt = h[x];
        v[cnt].to = y; v[cnt].w = w;
        h[x] = cnt++;
    }
};
Graph<int> G;

queue<int> Q;
int f[55], cur[55];
double l, r, m1;
int n, m, x, y, z, k;
pair<pair<int, int>, int> v[55];

bool bfs() {
    Q.push(0);
    while (!Q.empty()) {
        int x = Q.front();
        for (int i = G.h[x]; i != -1; i = G.v[i].nxt) {
            int to = G.v[i].to;
            if (f[to] == 0 && G.v[i].w > 0) {
                f[to] = f[x] + 1;
                Q.push(to);
            }
        }
        Q.pop();
    }
    return f[n - 1] != 0;
}

int dfs(int x, int y) {
    if (y <= 0 || x == n - 1) return y;
    int t;
    for (int i = cur[x]; i != -1; i = G.v[i].nxt) {
        int to = G.v[i].to;
        if (f[to] != f[x] + 1) continue;
        t = dfs(to, min(G.v[i].w, y));

        if (t > 0) {
            G.v[i].w -= t; G.v[i ^ 1].w += t;
            cur[x] = i;
            return t;
        }
    }
    return 0;
}

int dinic() {
    int ret = 0; memset(f, 0, sizeof(f)); f[0] = 1;
    for (int i = 0; i < n; ++i) cur[i] = G.h[i];
    while (bfs()) {
        int x = 0;
        while (x = dfs(0, INF))
            ret += x;
        memset(f, 0, sizeof(f)); f[0] = 1;
        for (int i = 0; i < n; ++i) cur[i] = G.h[i];
    }
    return ret;
}

int main(void) {
    n = read(); m = read(); k = read();
    for (int i = 0; i < m; ++i) {
        x = read() - 1; y = read() - 1; z = read();
        v[i] = mp(mp(x, y), z);
    }
    l = 0; r = 1000000.0;
    for (int i = 0; i < 200; ++i) {
        m1 = (l + r) / 2;
        memset(G.h, -1, sizeof(G.h));
        G.cnt = 0;
        for (int j = 0; j < m; ++j) {
            G.add(v[j].fi.fi, v[j].fi.se, min(k, (int)(v[j].se / m1)));
            G.add(v[j].fi.se, v[j].fi.fi, 0);
        }
        if (dinic() < k) r = m1;
        else l = m1;
    }
    printf("%.10lf\n", l * k);
}


/*
** Generic template
** avaicode 2017/2/19
** MIT License
*/

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

#define INF 2147480000
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SUM(x,y) accumulate(x,y,0)
#define gcd(x,y) (__gcd(x,y))
#define LOWBIT(x) (x&(-x))
#define CLR(x,y) memset(x,y,sizeof(x))
#define PD(x) printf("%d\n",(x))
#define PF(f) printf("%lf\n",(f))
#define PS(s) puts(s)
typedef long long LL;

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-')f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}

template<typename T>
struct Graph {
    enum { maxn = 55, maxm = 1005 };
    struct {
        int to, nxt;
        T w;
    } v[maxm];
    int h[maxn], cnt;
    Graph() { memset(h, -1, sizeof(h)); }
    void add(int x, int y, const T& w) {
        v[cnt].nxt = h[x];
        v[cnt].to = y; v[cnt].w = w;
        h[x] = cnt++;
    }
};
Graph<int> G;

queue<int> Q;
int f[55], cur[55];
double l, r, m1;
int n, m, x, y, z, k;
pair<pair<int, int>, int> v[505];

bool bfs() {
    Q.push(0);
    while (!Q.empty()) {
        int x = Q.front();
        for (int i = G.h[x]; i != -1; i = G.v[i].nxt) {
            int to = G.v[i].to;
            if (f[to] == 0 && G.v[i].w > 0) {
                f[to] = f[x] + 1;
                Q.push(to);
            }
        }
        Q.pop();
    }
    return f[n - 1] != 0;
}

int dfs(int x, int y) {
    if (y <= 0 || x == n - 1) return y;
    int t;
    for (int i = cur[x]; i != -1; i = G.v[i].nxt) {
        int to = G.v[i].to;
        if (f[to] != f[x] + 1) continue;
        t = dfs(to, min(G.v[i].w, y));

        if (t > 0) {
            G.v[i].w -= t; G.v[i ^ 1].w += t;
            cur[x] = i;
            return t;
        }
    }
    return 0;
}

int dinic() {
    int ret = 0; memset(f, 0, sizeof(f)); f[0] = 1;
    while (bfs()) {
        int x = 0;
        for (int i = 0; i < n; ++i) cur[i] = G.h[i];
        while (x = dfs(0, INF))
            ret += x;
        memset(f, 0, sizeof(f)); f[0] = 1;
    }
    return ret;
}

int main(void) {
    n = read(); m = read(); k = read();
    for (int i = 0; i < m; ++i) {
        x = read() - 1; y = read() - 1; z = read();
        v[i] = mp(mp(x, y), z);
    }
    l = 0; r = 1000000.0;
    for (int i = 0; i < 200; ++i) {
        m1 = (l + r) / 2;
        memset(G.h, -1, sizeof(G.h));
        G.cnt = 0;
        for (int j = 0; j < m; ++j) {
            G.add(v[j].fi.fi, v[j].fi.se, min(k, (int)(v[j].se / m1)));
            G.add(v[j].fi.se, v[j].fi.fi, 0);
        }
        if (dinic() < k) r = m1;
        else l = m1;
    }
    printf("%.10lf\n", l * k);
}


/*
** Generic template
** avaicode 2017/2/19
** MIT License
*/

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

#define INF 2147480000
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SUM(x,y) accumulate(x,y,0)
#define gcd(x,y) (__gcd(x,y))
#define LOWBIT(x) (x&(-x))
#define CLR(x,y) memset(x,y,sizeof(x))
#define PD(x) printf("%d\n",(x))
#define PF(f) printf("%lf\n",(f))
#define PS(s) puts(s)
typedef long long LL;

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-')f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}

template<typename T>
struct Graph {
    enum { maxn = 55, maxm = 1005 };
    struct {
        int to, nxt;
        T w;
    } v[maxm];
    int h[maxn], cnt;
    Graph() { memset(h, -1, sizeof(h)); }
    void add(int x, int y, const T& w) {
        v[cnt].nxt = h[x];
        v[cnt].to = y; v[cnt].w = w;
        h[x] = cnt++;
    }
};
Graph<int> G;

queue<int> Q;
int f[55];
double l, r, m1;
int n, m, x, y, z, k;
pair<pair<int, int>, int> v[55];

bool bfs() {
    Q.push(0);
    while (!Q.empty()) {
        int x = Q.front();
        for (int i = G.h[x]; i != -1; i = G.v[i].nxt) {
            int to = G.v[i].to;
            if (f[to] == 0 && G.v[i].w > 0) {
                f[to] = f[x] + 1;
                Q.push(to);
            }
        }
        Q.pop();
    }
    return f[n - 1] != 0;
}

int dfs(int x, int y) {
    if (y <= 0 || x == n - 1) return y;
    int s = 0, t;
    for (int i = G.h[x]; i != -1; i = G.v[i].nxt) {
        int to = G.v[i].to;
        if (f[to] != f[x] + 1) continue;
        t = dfs(to, min(G.v[i].w, y));
        s += t; y -= t;
        G.v[i].w -= t; G.v[i ^ 1].w += t;
        if (y <= 0) break;
    }
    return s;
}

int dinic() {
    int ret = 0; memset(f, 0, sizeof(f)); f[0] = 1;
    while (bfs())
    { ret += dfs(0, INF); memset(f, 0, sizeof(f)); f[0] = 1; }
    return ret;
}

int main(void) {
    n = read(); m = read(); k = read();
    for (int i = 0; i < m; ++i) {
        x = read() - 1; y = read() - 1; z = read();
        v[i] = mp(mp(x, y), z);
    }
    l = 0; r = 1000000.0;
    for (int i = 0; i < 200; ++i) {
        m1 = (l + r) / 2;
        memset(G.h, -1, sizeof(G.h));
        G.cnt = 0;
        for (int j = 0; j < m; ++j) {
            G.add(v[j].fi.fi, v[j].fi.se, min(k, (int)(v[j].se / m1)));
            G.add(v[j].fi.se, v[j].fi.fi, 0);
        }
        if (dinic() < k) r = m1;
        else l = m1;
    }
    printf("%.10lf\n", l * k);
}


/*
** Generic template
** avaicode 2017/2/19
** MIT License
*/

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;

#define INF 2147480000
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define SUM(x,y) accumulate(x,y,0)
#define gcd(x,y) (__gcd(x,y))
#define LOWBIT(x) (x&(-x))
#define CLR(x,y) memset(x,y,sizeof(x))
#define PD(x) printf("%d\n",(x))
#define PF(f) printf("%lf\n",(f))
#define PS(s) puts(s)
typedef long long LL;

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-')f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}

template<typename T>
struct Graph {
    enum { maxn = 55, maxm = 1005 };
    struct {
        int to, nxt;
        T w;
    } v[maxm];
    int h[maxn], cnt;
    Graph() { memset(h, -1, sizeof(h)); }
    void add(int x, int y, const T& w) {
        v[cnt].nxt = h[x];
        v[cnt].to = y; v[cnt].w = w;
        h[x] = cnt++;
    }
};
Graph<int> G;

queue<int> Q;
int f[55], cur[55];
double l, r, m1;
int n, m, x, y, z, k;
pair<pair<int, int>, int> v[55];

bool bfs() {
    Q.push(0);
    while (!Q.empty()) {
        int x = Q.front();
        for (int i = G.h[x]; i != -1; i = G.v[i].nxt) {
            int to = G.v[i].to;
            if (f[to] == 0 && G.v[i].w > 0) {
                f[to] = f[x] + 1;
                Q.push(to);
            }
        }
        Q.pop();
    }
    return f[n - 1] != 0;
}

int dfs(int x, int y) {
    if (y <= 0 || x == n - 1) return y;
    int t;
    for (int i = cur[x]; i != -1; i = G.v[i].nxt) {
        int to = G.v[i].to;
        if (f[to] != f[x] + 1) continue;
        t = dfs(to, min(G.v[i].w, y));

        if (t > 0) {
            G.v[i].w -= t; G.v[i ^ 1].w += t;
            cur[x] = i;
            return t;
        }
    }
    return 0;
}

int dinic() {
    int ret = 0; memset(f, 0, sizeof(f)); f[0] = 1;
    while (bfs()) {
        int x = 0;
        while (x = dfs(0, INF))
            ret += x;
        memset(f, 0, sizeof(f)); f[0] = 1;
        for (int i = 0; i < n; ++i) cur[i] = G.h[i];
    }
    return ret;
}

int main(void) {
    n = read(); m = read(); k = read();
    for (int i = 0; i < m; ++i) {
        x = read() - 1; y = read() - 1; z = read();
        v[i] = mp(mp(x, y), z);
    }
    l = 0; r = 1000000.0;
    for (int i = 0; i < 200; ++i) {
        m1 = (l + r) / 2;
        memset(G.h, -1, sizeof(G.h));
        G.cnt = 0;
        for (int j = 0; j < m; ++j) {
            G.add(v[j].fi.fi, v[j].fi.se, min(k, (int)(v[j].se / m1)));
            G.add(v[j].fi.se, v[j].fi.fi, 0);
        }
        if (dinic() < k) r = m1;
        else l = m1;
    }
    printf("%.10lf\n", l * k);
}


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

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

using namespace output;

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

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

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

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

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


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

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

using namespace output;

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

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

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

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

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


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

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

using namespace output;

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

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

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

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

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


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

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

using namespace output;

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

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

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

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

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


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

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

using namespace output;

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

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

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

void dfs(int n){
    for(auto v : g[n]){
        if(par[v]==-1&&cap[n][v]>0){
            par[v]=n;
            dfs(v);
        }
    }
}

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


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

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

using namespace output;

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

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

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

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

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


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

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

using namespace output;

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

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

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

void dfs(int n){
    for(auto v : g[n]){
        if(par[v]==-1&&cap[n][v]>0){
            par[v]=n;
            dfs(v);
        }
    }
}

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


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

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

using namespace output;

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

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

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

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

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


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

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

using namespace output;

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

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

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

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

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


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

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

using namespace output;

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

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

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

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

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