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 <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int mod=1000000007,MAX=103,INF=1<<30;
typedef pair<int,int> P;

struct edge{int to,cap,cost,rev;};

int V;
vector<edge> G[MAX];
int h[MAX];
int dist[MAX];
int prevv[MAX],preve[MAX];

void add_edge(int from,int to,int cap,int cost){
    G[from].push_back((edge){to,cap,cost,int(G[to].size())});
    G[to].push_back((edge){from,0,-cost,int(G[from].size()-1)});
}

int min_cost_flow(int s,int t,int f){
    int res=0;
    fill(h,h+V,0);
    
    while(f>0){
        priority_queue<P,vector<P>,greater<P>> que;
        fill(dist,dist+V,INF);
        dist[s]=0;
        que.push(P(0,s));
        while(!que.empty()){
            P p=que.top();que.pop();
            int v=p.second;
            if(dist[v]<p.first) continue;
            for(int i=0;i<G[v].size();i++){
                edge &e=G[v][i];
                if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
                    dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
                    prevv[e.to]=v;
                    preve[e.to]=i;
                    que.push(P(dist[e.to],e.to));
                }
            }
        }
        
        if(dist[t]==INF){
            return -1;
        }
        for(int v=0;v<V;v++){
            h[v]+=dist[v];
        }
        
        int d=f;
        for(int v=t;v!=s;v=prevv[v]){
            d=min(d,G[prevv[v]][preve[v]].cap);
        }
        f-=d;
        res+=d*h[t];
        for(int v=t;v!=s;v=prevv[v]){
            edge &e=G[prevv[v]][preve[v]];
            e.cap-=d;
            G[v][e.rev].cap+=d;
        }
    }
    return res;
}//sからtへの流量fの最小費用流、流せない場合は-1

int main(){

    int E,F;cin>>V>>E>>F;
    for(int i=0;i<E;i++){
        int a,b,c,d;cin>>a>>b>>c>>d;
        add_edge(a,b,c,d);
    }
    
    int ans=min_cost_flow(0,V-1,F);
    
    cout<<ans<<endl;
}