Problem: Examples

Input

4 5 2
0 1 2 1
0 2 1 2
1 2 1 1
1 3 1 3
2 3 2 1


Output

6


Input




Output

Solution (in CPP):

Solution:
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <bitset>
using namespace std;

#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repl(i,0,n)
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define fi first
#define se second

#define INF 2147483600

template<typename T>
class MinCostFlow{
private:
  struct edge{int to; T cap, cost; int rev;};
  using P = pair<int,int>;
  vector<vector<edge> > Graph;
  vector<int> prevv, preve;
  vector<T> h, d; // ??????????????£?????????????????¢
public:
  MinCostFlow(int v){
    // ????????°v??§?????????
    Graph.resize(v);
    prevv.resize(v);
    preve.resize(v);
    h.resize(v);
    d.resize(v);
  }
  T min_cost_flow(int s, int t, T f){
    T res = 0;
    fill(all(h), 0);
    while(f>0){
      priority_queue<P, vector<P>, greater<P>> pq;
      fill(all(d), INF);
      d[s] = 0;
      pq.push(mp(0,s));
      while(!pq.empty()){
        auto p = pq.top(); pq.pop();
        int v = p.se;
        if(d[v] < p.fi) continue;
        rep(i,Graph[v].size()){
          edge &e = Graph[v][i];
          if(e.cap > 0 && d[e.to] > d[v] + e.cost + h[v] - h[e.to]){
            d[e.to] = d[v] + e.cost + h[v] - h[e.to];
            prevv[e.to] = v;
            preve[e.to] = i;
            pq.push(mp(d[e.to], e.to));
          }
        }
      }
      if(d[t] == INF) return -1;
      rep(i,Graph.size()) h[i] += d[i];

      T nf = f;
      for(int v=t; v!=s; v = prevv[v]){
        nf = min(nf, Graph[prevv[v]][preve[v]].cap);
      }
      f -= nf;
      res += nf * h[t];
      for(int v=t; v!=s; v=prevv[v]){
        edge &e = Graph[prevv[v]][preve[v]];
        e.cap -= nf;
        Graph[v][e.rev].cap += nf;
      }
    }
    return res;
  }
  void add_edge(int from ,int to, T cap, T cost){
    Graph[from].pb(((edge){to, cap, cost, (int)Graph[to].size()}));
    Graph[to].pb(((edge){from, 0, -cost, (int)Graph[from].size()-1}));
  }
};

int main(){
  int v,e,f;
  cin>>v>>e>>f;
  MinCostFlow<int> flow(v);
  rep(i,e){
    int a,b,c,d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    flow.add_edge(a, b, c, d);
  }

  cout<<flow.min_cost_flow(0, v-1, f)<<endl;

  return 0;
}