Problem:
Problem F
N 階ダンジョンと K 人の勇者たち
あなたは
K
人からなる勇者グループの一員である．あなたたち勇者グループの目的は
N
階ダンジョンの最終層（第
N
階層）にいる魔王を倒すことであるが，何回このダンジョンに挑んでも魔王に手も足も出ずに困っている．
手も足も出ない原因の一つは，各階層に存在する門番モンスターの存在である．第
1
層から第
N-1
階層までの各階層では門番モンスターが次の階層への階段を守っており，彼らを倒して進んでいくと魔王の下に辿り着くまでに消耗してしまう．
そこで，あなたたちはダンジョンに潜む
M
人の魔女を頼ることにした．
i
番目の魔女はダンジョンの第
S
i
階層に潜んでおり，第
S
i
階層にいるときにお金を払うと，その人をより深い階層である第
T
i
階層までワープさせてくれる．魔女は最初の一人目は
C
i
円でワープさせてくれるが，足元を見るのが得意なので，一人ワープさせるにつれて
D
i
円ずつ金額を上乗せしてくることがわかっている．より正確に表すと，
i
番目の魔女がこれまで
j
人ワープさせていた場合，
i
番目の魔女の次のワープにかかる金額は
C
i
+ j × D
i
である．一人の魔女が複数人を同時にワープさせることはないため，複数人で同時に魔女のもとへ訪れたからといって金額が安くなることはない．
また，魔女にお金を払ってワープさせてもらうと，その魔女が知っている魔王に関する情報を教えてくれる，ということがわかった．あなたたちは万全を期すために，
M
人全員の魔女から魔王に関する情報を仕入れたい．
よって，あなたたちは
K
人バラバラにダンジョンの第
1
階層に入り，それぞれが魔女から情報を仕入れ，第
N
階層で
K
人全員で集合することにした．このときに情報を統合すると
M
人の魔女全員分の情報が集まっているようにしたい．なお，門番モンスターを倒せば魔女に頼らなくても 1 つ上または下の階層に移動できるが，門番モンスターとの戦闘による消耗を避けるため，魔女によるワープ以外では階層を跨がないようにしたい．
あなたたちはお金を無限に持っているわけではないので，なるべく魔女に払う金額の合計を少なくしたい．
K
人を最適に行動させたとき，魔女に払う金額の合計は最小でいくらになるだろうか？
Input
入力は複数のデータセットからなる．各データセットは次の形式で表される．
N
M
K
S
1
T
1
C
1
D
1
...
S
M
T
M
C
M
D
M
N
はダンジョンの階層数を表す整数であり，
2 ≤ N ≤ 500
を満たす．
M
は魔女の人数を表す整数であり，
1 ≤ M ≤ 500
を満たす．
K
は勇者グループの人数を表す整数であり，
1 ≤ K ≤ 5,000
を満たす．
各
i = 1, 2, ... , M
について，
S
i
は
i
番目の魔女がいる階層，
T
i
はワープ先の階層，
C
i
はワープの初期金額，
D
i
は上乗せ金額を表す整数であり，
1 ≤ S
i
< T
i
≤ N, 1 ≤ C
i
≤ 10
9
, 1 ≤ D
i
≤ 10
9
を満たす．
i ≠ j
なる
i, j
について，
(S
i
, T
i
) ≠ (S
j
, T
j
)
を満たす．
各魔女について，その魔女のワープを経由しつつ第
1
階層から第
N
階層へ魔女のワープのみを使用して到達する方法が存在する．
入力の終わりは 3 つのゼロからなる行で表される．入力に含まれるデータセットは 50 個以下である．
Output
各データセットに対して，魔女に払う金額の最小値を出力せよ．問題文中の条件を満たすような行動が存在しない場合は代わりに -1 と出力せよ．
Sample Input
3 2 5
1 2 90 2
2 3 10 1
3 3 6
1 2 1 1
2 3 1 4
1 3 18 2
3 3 3
1 2 1 1
2 3 1 4
1 3 18 2
3 3 1
1 2 1 1
2 3 1 4
1 3 18 2
6 7 50
1 2 55 4
1 3 86 3
2 4 13 84
3 4 31 51
3 5 10 78
4 6 1 71
5 6 39 35
0 0 0
Output for the Sample Input
530
76
27
-1
72445

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T> using V = vector<T>;
const ll INF = 1ll << 60;
#define rep(i,n) for(int i=0; i<int(n); i++)
template<class A, class B> void chmax(A& l, const B& r){ if(l < r) l = r; }
template<class A, class B> void chmin(A& l, const B& r){ if(r < l) l = r; }


template <class E> using V = vector<E>;


struct MCF {
  using Cap = ll;
  using Cost = ll;
  Cost INF = 1ll << 60;
  struct Edge{
      int from;
      int to;
      Cost cost;
      Cap cap;
  };
  int N;
  V<Edge> E;
  V<V<int>> g;
  V<Cost> P;
  MCF(int n) : N(n), g(n), P(n,0){}
  int addEdge(int u, int v, Cap cap, Cost cost){
    int e = E.size();
    g[u].push_back(e);
    g[v].push_back(e+1);
    E.push_back({ u, v, cost, cap });
    E.push_back({ v, u, -cost, 0 });
    return e;
  }
  pair<Cap,Cost> flowuni(int s, int t, Cap lim){
    V<Cost> dist(N, INF);
    V<int> par(N, -1);
    V<Cap> fl(N, lim);
    priority_queue<pair<Cost,int>> que;
    dist[s] = 0; que.push({ 0, s });
    while(que.size()){
      auto [d,v] = que.top(); que.pop();
      if(dist[v] != -d) continue;
      if(v == t) break;
      for(auto e : g[v]) if(E[e].cap){
        int w = E[e].to;
        Cost nd = -d + P[v] + E[e].cost - P[w];
        if(dist[w] <= nd) continue;
        dist[w] = nd;
        que.push({ -nd, w });
        par[w] = e;
        fl[w] = min(fl[v], E[e].cap);
      }
    }
    if(par[t] < 0) return { 0, 0 };
    lim = fl[t];
    for(int p=t; p!=s; ){
      int e = par[p];
      E[e].cap -= lim;
      E[e^1].cap += lim;
      p = E[e^1].to;
    }
    for(int i=0; i<N; i++) if(i == s || par[i] >= 0){
      P[i] += dist[i] - dist[t];
    }
    return { P[t] - P[s], lim };
  }
  V<pair<Cap, Cost>> slope(int s, int t, Cap lim){
    V<pair<Cap, Cost>> res;
    res.push_back({0,0});
    Cap fl = 0;
    Cost co = 0;
    while(fl < lim){
      auto [u,v] = flowuni(s, t, lim - fl);
      if(v == 0) break;
      res.push_back({ fl += v, co += u*v });
    }
    return res;
  }
  pair<Cap, Cost> flow(int s, int t, Cap lim){
    return slope(s, t, lim).back();
  }
};


void testcase(){
    ll N, M, K; cin >>  N >> M >> K;
    if(N == 0) exit(0);
    vector<ll> S(M), T(M), C(M), D(M);
    rep(k,M) cin >> S[k] >> T[k] >> C[k] >> D[k];
    rep(k,M){ S[k]--; T[k]--; }

    MCF mcf(N+2);
    ll src = N, snk = N+1;
    mcf.addEdge(src, 0, K, 0);
    mcf.addEdge(N-1, snk, K, 0);

    ll ans = 0;

    vector<ll> eflow(M), eid(M);
    rep(i,M){
        mcf.addEdge(src, T[i], 1, 0);
        mcf.addEdge(S[i], snk, 1, 0);
        eid[i] = mcf.addEdge(S[i], T[i], K, C[i] + D[i]);
        ans += C[i];
    }

    rep(k,M+K){
        auto res = mcf.flow(src, snk, 1);
        if(res.first == 0){ cout << "-1\n"; return; }
        ans += res.second;
        rep(i,M){
            eflow[i] = mcf.E[eid[i]^1].cap;
            mcf.E[eid[i]].cost = C[i] + ll(D[i]) * (eflow[i] + 1);
            mcf.E[eid[i]^1].cost = -(C[i] + ll(D[i]) * eflow[i]);
        }
    }

    cout << ans << "\n";
}


int main(){
    cin.tie(0)->sync_with_stdio(0);
    //int T; cin >> T;
    //rep(t,T)
    while(1) testcase();
    return 0;
}
accuracy: 1
time_ms: 2070
memory_kb: 3608
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

bool solve(){
    int n, m, k; cin >> n >> m >> k;
    if(n == 0 && m == 0 && k == 0) return false;
    struct E {
        int to, rev;
        ll d;
        ll cap;
        ll cost;
    };
    vector<vector<E>> g(n+2);
    auto add_edge = [&](int from, int to, int cap, ll c, ll d) {
        g[from].push_back(E{to, int(g[to].size()), d, cap, c+d});
        g[to].push_back(E{from, int(g[from].size())-1, d, 0, -c});
    };
    ll sum_c = 0;
    int source = n, sink = n+1;
    for(int i = 0; i < m; i++) {
        int s, t; ll c, d; cin >> s >> t >> c >> d; s--; t--;
        sum_c += c;
        add_edge(source, t, 1, 0, 0);
        add_edge(s, sink, 1, 0, 0);
        add_edge(s, t, k, c, d);
    }
    add_edge(source, 0, k, 0, 0);
    add_edge(n-1, sink, k, 0, 0);
    ll INF = 1LL<<61;
    ll ans = sum_c;
    vector<ll> pot(n+2);
    for(int t = 0; t < k+m; t++) {
        vector<ll> dist(n+2, INF);
        vector<pair<int, int>> prev(n+2); // (vertex, id of g)
        dist[source] = 0;
        using P = pair<ll, int>;
        priority_queue<P, vector<P>, greater<P>> pq;
        pq.emplace(dist[source], source);
        while(!pq.empty()) {
            auto [d, u] = pq.top(); pq.pop();
            if(d > dist[u]) continue;
            for(int i = 0; i < ssize(g[u]); i++) {
                const auto& e = g[u][i];
                if(e.cap == 0) continue;
                int v = e.to;
                ll ndist = d + e.cost + pot[u] - pot[v];
                if(dist[v] == INF || dist[v] > ndist) {
                    dist[v] = ndist;
                    prev[v] = {u, i};
                    pq.emplace(dist[v], v);
                }
            }
        }
        if(dist[sink] == INF) {
            cout << "-1\n";
            return true;
        }
        int cur = sink;
        while(cur != source) {
            auto [ncur, id] = prev[cur];
            auto& e = g[ncur][id];
            auto& re = g[cur][e.rev];
            ans += e.cost;
            re.cost = -e.cost;
            e.cost += e.d;
            e.cap--;
            re.cap++;
            cur = ncur;
        }
        for(int i = 0; i < n+2; i++) pot[i] += dist[i];
    }
    cout << ans << '\n';
    return true;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    while(solve());
}
accuracy: 1
time_ms: 1700
memory_kb: 3840
final_rank: 9

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T, typename S = T> S SUM(const vector<T> &a) {
    return accumulate(ALL(a), S(0));
}
template <typename S, typename T = S> S POW(S a, T b) {
    S ret = 1, base = a;
    for (;;) {
        if (b & 1)
            ret *= base;
        b >>= 1;
        if (b == 0)
            break;
        base *= base;
    }
    return ret;
}
template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define debug 1
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define debug 0
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 2 "library/Utility/random.hpp"

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]
    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]
    return get(R - L) + L;
}
double uniform() {
    return double(get(1000000000)) / 1000000000;
}
string str(int n) {
    string ret;
    rep(i, 0, n) ret += get('a', 'z');
    return ret;
}
template <typename Iter> void shuffle(Iter first, Iter last) {
    if (first == last)
        return;
    int len = 1;
    for (auto it = first + 1; it != last; it++) {
        len++;
        int j = get(0, len - 1);
        if (j != len - 1)
            iter_swap(it, first + j);
    }
}
template <typename T> vector<T> select(int n, T L, T R) { // [L,R]
    if (n * 2 >= R - L + 1) {
        vector<T> ret(R - L + 1);
        iota(ALL(ret), L);
        shuffle(ALL(ret));
        ret.resize(n);
        return ret;
    } else {
        unordered_set<T> used;
        vector<T> ret;
        while (SZ(used) < n) {
            T x = get(L, R);
            if (!used.count(x)) {
                used.insert(x);
                ret.push_back(x);
            }
        }
        return ret;
    }
}

void relabel(int n, vector<pair<int, int>> &es) {
    shuffle(ALL(es));
    vector<int> ord(n);
    iota(ALL(ord), 0);
    shuffle(ALL(ord));
    for (auto &[u, v] : es)
        u = ord[u], v = ord[v];
}
template <bool directed, bool multi, bool self>
vector<pair<int, int>> genGraph(int n, int m) {
    vector<pair<int, int>> cand, es;
    rep(u, 0, n) rep(v, 0, n) {
        if (!self and u == v)
            continue;
        if (!directed and u > v)
            continue;
        cand.push_back({u, v});
    }
    if (m == -1)
        m = get(SZ(cand));
    // chmin(m, SZ(cand));
    vector<int> ord;
    if (multi)
        rep(_, 0, m) ord.push_back(get(SZ(cand) - 1));
    else {
        ord = select(m, 0, SZ(cand) - 1);
    }
    for (auto &i : ord)
        es.push_back(cand[i]);
    relabel(n, es);
    return es;
}
vector<pair<int, int>> genTree(int n) {
    vector<pair<int, int>> es;
    rep(i, 1, n) es.push_back({get(i - 1), i});
    relabel(n, es);
    return es;
}
}; // namespace Random

/**
 * @brief Random
 */
#line 4 "sol.cpp"

template <bool neg = 0, bool dag = 0> struct MinCostFlow {
    using P = pair<ll, int>;
    struct edge {
        int to;
        ll cap, cost, diff;
        int rev;
        edge(int to, ll cap, ll cost, ll diff, int rev)
            : to(to), cap(cap), cost(cost), diff(diff), rev(rev) {}
    };
    int n;
    vector<vector<edge>> g;
    vector<ll> dist, pot;
    vector<int> vpre, epre;
    MinCostFlow(int n) : n(n), g(n), dist(n), pot(n), vpre(n), epre(n) {}
    void add_edge(int u, int v, ll cap, ll cost, ll diff) {
        g[u].push_back({v, cap, cost, diff, SZ(g[v])});
        g[v].push_back(
            {u, 0, -cost + diff, diff,
             SZ(g[u]) - 1}); // フローを増やしたときにcostが一致する必要がある
    }
    void bellmanford(int s) {
        pot.assign(n, INF);
        pot[s] = 0;
        for (;;) {
            bool upd = 0;
            rep(v, 0, n) if (pot[v] != INF) {
                for (auto &e : g[v]) {
                    if (e.cap > 0 and chmin(pot[e.to], pot[v] + e.cost))
                        upd = 1;
                }
            }
            if (!upd)
                break;
        }
    }
    void bfs(int s) {
        vector<int> deg(n), tsort;
        queue<int> que;
        rep(v, 0, n) for (auto &e : g[v]) {
            if (e.cap > 0)
                deg[e.to]++;
        }
        rep(v, 0, n) if (deg[v] == 0) {
            que.push(v);
        }
        while (!que.empty()) {
            int v = que.front();
            tsort.push_back(v);
            que.pop();
            for (auto &e : g[v])
                if (e.cap > 0) {
                    deg[e.to]--;
                    if (deg[e.to] == 0)
                        que.push(e.to);
                }
        }
        pot.assign(n, INF);
        pot[s] = 0;
        for (auto &v : tsort)
            for (auto &e : g[v])
                if (e.cap > 0) {
                    chmin(pot[e.to], pot[v] + e.cost);
                }
    }
    ll run(int s, int t, ll flow) {
        ll ret = 0;
        if (neg) {
            if (dag)
                bfs(s);
            else
                bellmanford(s);
        }
        while (flow) {
            dist.assign(n, INF);
            priority_queue<P, vector<P>, greater<P>> pq;
            dist[s] = 0;
            pq.push({0, s});
            while (!pq.empty()) {
                auto [d, v] = pq.top();
                pq.pop();
                if (dist[v] != d)
                    continue;
                rep(j, 0, SZ(g[v])) {
                    auto e = g[v][j];
                    if (e.cap > 0 and
                        chmin(dist[e.to],
                              dist[v] + e.cost + pot[v] - pot[e.to])) {
                        vpre[e.to] = v;
                        epre[e.to] = j;
                        pq.push({dist[e.to], e.to});
                    }
                }
            }
            if (dist[t] == INF)
                return -INF;
            rep(v, 0, n) {
                if (pot[v] == INF or dist[v] == INF)
                    pot[v] = INF;
                else
                    pot[v] += dist[v];
            }
            ll f = flow;
            for (int v = t; v != s; v = vpre[v])
                chmin(f, g[vpre[v]][epre[v]].cap);
            assert(f > 0);
            f = 1;
            ret += pot[t], flow -= 1;
            for (int v = t; v != s; v = vpre[v]) {
                auto &e = g[vpre[v]][epre[v]];
                e.cap -= 1;
                e.cost += e.diff;
                g[v][e.rev].cap += f;
                g[v][e.rev].cost -= e.diff;
            }
        }
        return ret;
    }
};

int main() {
    for (;;) {
        int n, m, k;
        read(n, m, k);
        if (n == 0)
            break;

        int S = n, T = n + 1;
        MinCostFlow<0, 0> mcf(n + 2);
        mcf.add_edge(S, 0, k, 0, 0);
        mcf.add_edge(n - 1, T, k, 0, 0);
        rep(_, 0, m) {
            int u, v, c, d;
            read(u, v, c, d);
            u--, v--;

            mcf.add_edge(S, v, 1, c, d);
            mcf.add_edge(u, T, 1, 0, 0);
            mcf.add_edge(u, v, inf, c + d, d);
            k++;
        }
        ll ret = mcf.run(S, T, k);
        chmax(ret, -1LL);
        print(ret);
    }
    return 0;
}
accuracy: 1
time_ms: 2010
memory_kb: 3968
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

bool solve(){
    int n, m, k; cin >> n >> m >> k;
    if(n == 0 && m == 0 && k == 0) return false;
    struct E {
        int to, rev;
        ll d;
        ll cap;
        ll cost;
    };
    vector<vector<E>> g(n+2);
    auto add_edge = [&](int from, int to, int cap, ll c, ll d) {
        g[from].push_back(E{to, int(g[to].size()), d, cap, c+d});
        g[to].push_back(E{from, int(g[from].size())-1, d, 0, -c});
    };
    ll sum_c = 0;
    int source = n, sink = n+1;
    for(int i = 0; i < m; i++) {
        int s, t; ll c, d; cin >> s >> t >> c >> d; s--; t--;
        sum_c += c;
        add_edge(source, t, 1, 0, 0);
        add_edge(s, sink, 1, 0, 0);
        add_edge(s, t, k, c, d);
    }
    add_edge(source, 0, k, 0, 0);
    add_edge(n-1, sink, k, 0, 0);
    ll INF = 1LL<<61;
    ll ans = sum_c;
    for(int t = 0; t < k+m; t++) {
        vector<ll> dist(n+2, INF);
        vector<pair<int, int>> prev(n+2); // (vertex, id of g)
        dist[source] = 0;
        using P = pair<ll, int>;
        priority_queue<P, vector<P>, greater<P>> pq;
        pq.emplace(dist[source], source);
        while(!pq.empty()) {
            auto [d, u] = pq.top(); pq.pop();
            if(d > dist[u]) continue;
            for(int i = 0; i < ssize(g[u]); i++) {
                const auto& e = g[u][i];
                if(e.cap == 0) continue;
                int v = e.to;
                ll ndist = d + e.cost;
                if(dist[v] == INF || dist[v] > ndist) {
                    dist[v] = ndist;
                    prev[v] = {u, i};
                    pq.emplace(dist[v], v);
                }
            }
        }
        if(dist[sink] == INF) {
            cout << "-1\n";
            return true;
        }
        int cur = sink;
        while(cur != source) {
            auto [ncur, id] = prev[cur];
            auto& e = g[ncur][id];
            auto& re = g[cur][e.rev];
            ans += e.cost;
            re.cost = -e.cost;
            e.cost += e.d;
            e.cap--;
            re.cap++;
            cur = ncur;
        }
    }
    cout << ans << '\n';
    return true;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    while(solve());
}
accuracy: 1
time_ms: 2120
memory_kb: 3712
final_rank: 8

code_snippet: // AOJ #3297 Nth Floor Dungeon and K Brave Men
// 2025.4.27

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = (1LL<<60);

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct Edge {
    int to, rev, cap;
    ll cost;
    int id;
};

vector<vector<Edge>> G;
vector<ll> C, D, used;
vector<pair<int,int>> posF, posR;

void addEdge(int u, int v, int cap, ll cost, int id){
    G[u].push_back({v, (int)G[v].size(), cap, cost, id});
    G[v].push_back({u, (int)G[u].size()-1, 0, -cost, -id});
}

int main(){
    while(true){
        int N = Cin(), M = Cin(), K = Cin();
        if(N==0) break;

        vector<int> S(M), T(M);
        C.assign(M, 0);
        D.assign(M, 0);
        for(int i = 0; i < M; i++) S[i] = Cin(), T[i] = Cin(), C[i] = Cin(), D[i] = Cin();

        int SRC = 0, SNK = N+1;
        G.assign(N+2, {});

        posF.resize(M);
        posR.resize(M);
        used.assign(M, 1);
        ll LB = 0;
        for(int i = 0; i < M; i++){
            LB += C[i];
            int u = S[i], v = T[i];
            posF[i] = {u, (int)G[u].size()};
            addEdge(u, v, K-1, C[i] + D[i], i+1);
            posR[i] = {v, (int)G[v].size() - 1};
        }

        vector<ll> a(N+2, 0);
        for(int i = 0; i < M; i++){
            a[S[i]] -= 1;
            a[T[i]] += 1;
        }
        a[N] -= K;
        a[1] += K;

        ll demand = 0;
        for(int v = 1; v <= N; v++){
            if(a[v] > 0){
                addEdge(SRC, v, (int)a[v], 0, 0);
                demand += a[v];
            } else if(a[v] < 0) addEdge(v, SNK, (int)(-a[v]), 0, 0);
        }

        ll flow = 0, cost = 0;
        int V = N+2;
        vector<ll> dist(V);
        vector<int> pv(V), pe(V);
        while(flow < demand){
            fill(dist.begin(), dist.end(), INF);
            vector<char> inq(V, 0);
            queue<int> q;
            dist[SRC] = 0;
            inq[SRC] = 1;
            q.push(SRC);

            while(!q.empty()){
                int u = q.front(); q.pop();
                inq[u] = 0;
                for(int ei = 0; ei < (int)G[u].size(); ei++){
                    auto &e = G[u][ei];
                    if(e.cap > 0 && dist[e.to] > dist[u] + e.cost){
                        dist[e.to] = dist[u] + e.cost;
                        pv[e.to] = u;
                        pe[e.to] = ei;
                        if(!inq[e.to]){
                            inq[e.to] = 1;
                            q.push(e.to);
                        }
                    }
                }
            }
            if(dist[SNK] == INF) break;

            int v = SNK;
            while(v != SRC){
                int u = pv[v], ei = pe[v];
                auto &e = G[u][ei];
                e.cap--;
                G[v][e.rev].cap++;

                if(e.id > 0){
                    int i = e.id - 1;
                    used[i]++;
                    auto &fwd = G[posF[i].first][posF[i].second];
                    fwd.cost = C[i] + used[i] * D[i];
                    auto &bak = G[posR[i].first][posR[i].second];
                    bak.cost = -(C[i] + (used[i]-1) * D[i]);
                } else if(e.id < 0){
                    int i = -e.id - 1;
                    used[i]--;
                    auto &fwd = G[posF[i].first][posF[i].second];
                    fwd.cost = C[i] + used[i] * D[i];
                    auto &bak = G[posR[i].first][posR[i].second];
                    bak.cost = -(C[i] + (used[i]-1) * D[i]);
                }
                v = u;
            }
            flow++;
            cost += dist[SNK];
        }
        if(flow < demand) Cout(-1);
        else Cout(cost + LB);
    }
    return 0;
}
accuracy: 1
time_ms: 2530
memory_kb: 3364
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
int main(){
    while(1){
        int N;ll M,K;cin>>N>>M>>K;
        if(!N)return 0;
        struct edge{
            int from,to;
            ll cap,C,D,flow;
        };
        ll ans=0;
        vector<edge>es;
        REP(_,M){
            int s,t;ll c,d;cin>>s>>t>>c>>d;s--;t--;
            ans+=c;
            es.emplace_back(edge{s,t,K-1,c,d,0});
            es.emplace_back(edge{N,t,1,0,0,0});
            es.emplace_back(edge{s,N+1,1,0,0,0});
        }
        es.emplace_back(edge{N,0,K,0,0,0});
        es.emplace_back(edge{N-1,N+1,K,0,0,0});
        vector<vector<int>>E(N+2);
        REP(i,es.size()){
            E[es[i].from].emplace_back(i);
            E[es[i].to].emplace_back(-1-i);
        }

        K+=M;
        while(K){
            vector<ll>D(N+2,1e18);
            vector<int>pre(N+2);
            D[N]=0;
            using pi=pair<ll,ll>;
            priority_queue<pi,vector<pi>,greater<pi>>Q;
            Q.emplace(pi(0,N));
            while(!Q.empty()){
                int v=Q.top().second;
                ll d=Q.top().first;
                Q.pop();
                if(D[v]!=d)continue;
                for(int i:E[v]){
                    if(i>=0){
                        if(es[i].flow<es[i].cap&&D[es[i].to]>d+es[i].C+es[i].D*(es[i].flow+1)){
                            D[es[i].to]=d+es[i].C+es[i].D*(es[i].flow+1);
                            pre[es[i].to]=i;
                            Q.emplace(pi(D[es[i].to],es[i].to));
                        }
                    }
                    else{
                        if(es[-1-i].flow&&D[es[-1-i].from]>d-es[-1-i].C-es[-1-i].D*es[-1-i].flow){
                            D[es[-1-i].from]=d-es[-1-i].C-es[-1-i].D*es[-1-i].flow;
                            pre[es[-1-i].from]=i;
                            Q.emplace(pi(D[es[-1-i].from],es[-1-i].from));
                        }
                    }
                }
            }
            if(D[N+1]==1e18)break;
            K--;
            ans+=D[N+1];
            int v=N+1;
            while(v!=N){
                int i=pre[v];
                if(i>=0)es[i].flow++,v=es[i].from;
                else es[-1-i].flow--,v=es[-1-i].to;
            }
        }
        if(K)ans=-1;
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 3250
memory_kb: 3544
final_rank: 6

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

using Cap  = i128;
using Cost = i128;
using Func = std::function<Cost(Cap)>;
const Cost INF64  = 1e18;
const Cost INF128 = 1e36;

struct mcf_graph {
    struct edge {
        int to, rev;
        Cap cap, flow;
        Func func;
    };

    int n;
    vector<vector<edge>> g;
    vector<Cost> h, dist;
    vector<int> prevv, preve;
    mcf_graph(int n) : n(n), g(n) {}

    void add_edge(int from, int to, Cap cap, Func func) {
        g[from].push_back(edge{to, int(g[to].size()), cap, 0, func});
        g[to].push_back(edge{from, int(g[from].size()) - 1, cap, cap, [cap, func](Cap i) { return - func(cap - i - 1); }});
    };

    Cost flow(int s, int t, Cap f) {
        Cost res = 0;
        h.assign(n, 0);
        prevv.assign(n, -1);
        preve.assign(n, -1);
        while(f > 0) {
            using P = pair< Cost, int >;
            priority_queue<P, vector<P>, greater<P>> que;
            dist.assign(n, INF128);
            que.push({dist[s] = 0, s});
            while(not que.empty()) {
                auto [d, v] = que.top(); que.pop();
                if(dist[v] < d) continue;
                for(int i = 0; i < int(g[v].size()); i++) {
                    edge &e = g[v][i];
                    Cost nd = dist[v] + e.func(e.flow) + (h[v] - h[e.to]);
                    if(e.flow < e.cap and dist[e.to] > nd) {
                        prevv[e.to] = v;
                        preve[e.to] = i;
                        que.push({dist[e.to] = nd, e.to});
                    }
                }
            }
            if(dist[t] == INF128) return -1;
            for(int v = 0; v < n; v++) h[v] += dist[v];

            f -= 1;
            res += h[t];
            for(int v = t; v != s; v = prevv[v]) {
                edge& e = g[prevv[v]][preve[v]];
                e.flow += 1;
                g[v][e.rev].flow -= 1;
            }
        }
        return res;
    }
};

Cost solve(int N, int M, int K) {
    mcf_graph G(1 + N + 1);
    const int S = N, T = S + 1;
    auto F = [&](Cost base, Cost diff) -> Func {
        return [base, diff](Cap i) { return base + diff * Cost(i); };
    };

    Cost sum = 0;
    for(int _ : rep(M)) {
        int from = in(), to = in(); from--, to--;
        Cost base = in(), diff = in();
        G.add_edge(from, to, K - 1, F(base + diff, diff));
        G.add_edge(S, to, 1, F(0, 0));
        G.add_edge(from, T, 1, F(0, 0));
        sum += base;
    }
    G.add_edge(N - 1, 0, K, F(0, 0));

    Cost valid = G.flow(S, T, M);
    if(valid != -1) {
        Cost cost = G.flow(0, N - 1, K);
        return sum + valid + cost;
    } else {
        return -1;
    }
}

int main() {
    while(true) {
        int N = in(), M = in(), K = in();
        if(N == 0) return 0;
        print(solve(N, M, K));
    }
}
accuracy: 1
time_ms: 4690
memory_kb: 4112
final_rank: 12

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

using ll = long long;

template<class flow_t = long long, class cost_t = long long>
struct PrimalDual
{
    const cost_t INF;
    
    struct edge
    {
        int to;
        int rev;
        flow_t cap;
        cost_t cost;
        cost_t diff;
    };
    
    int siz;
    vector<vector<edge>> graph;
    vector<cost_t> potential, min_cost;
    vector<int> prev_v, prev_id;
    
    PrimalDual(int _n) : siz(_n), INF(1e18), graph(_n) { }
    
    void add_edge(int from, int to, flow_t cap, cost_t cost, cost_t diff)
    {
        assert(from < siz && to < siz);
        graph[from].emplace_back((edge){to, (int)graph[to].size(), cap, cost, diff});
        graph[to].emplace_back((edge){from, (int)graph[from].size() - 1, 0, -cost + diff, diff});
    }
    
    cost_t min_cost_flow(int s, int t, flow_t f)
    {
        cost_t ret = 0;
        using Pi = pair<cost_t, int>;
        priority_queue<Pi, vector<Pi>, greater<Pi>> pq;
        potential.assign(siz, 0);
        prev_v.assign(siz, -1);
        prev_id.assign(siz, -1);
        
        while (f > 0)
        {
            min_cost.assign(siz, INF);
            pq.emplace(0, s);
            min_cost[s] = 0;
            
            while (!pq.empty())
            {
                auto [cost, v] = pq.top();
                pq.pop();
                
                if (min_cost[v] < cost) continue;
                for (int i = 0; i < graph[v].size(); ++i)
                {
                    auto &e = graph[v][i];
                    cost_t next_cost = min_cost[v] + e.cost + (potential[v] - potential[e.to]);
                    if (e.cap > 0 && min_cost[e.to] > next_cost)
                    {
                        min_cost[e.to] = next_cost;
                        prev_v[e.to] = v;
                        prev_id[e.to] = i;
                        pq.emplace(min_cost[e.to], e.to);
                    }
                }
            }
            
            if (min_cost[t] == INF)
            {
                return -1;
            }
            
            for (int v = 0; v < siz; ++v) potential[v] += min_cost[v];
            flow_t addflow = f;
            for (int v = t; v != s; v = prev_v[v])
            {
                addflow = min(addflow, graph[prev_v[v]][prev_id[v]].cap);
            }
            addflow = 1; // ここ変更した
            f -= addflow;
            ret += addflow * potential[t];
            for (int v = t; v != s; v = prev_v[v])
            {
                auto &e = graph[prev_v[v]][prev_id[v]];
                e.cap -= addflow;
                e.cost += e.diff;
                
                auto &re = graph[e.to][e.rev];
                re.cap += addflow;
                re.cost -= re.diff;
            }
        }
        return ret;
    }
};


bool is_end = false;

void solve()
{
    ll N, M, K; cin >> N >> M >> K;
    if (N == 0)
    {
        is_end = true;
        return;
    }
    
    int s = 0, t = N - 1;
    int S = N, T = N + 1;
    PrimalDual<ll, ll> mcf(T + 1);
    mcf.add_edge(S, s, K, 0, 0);
    mcf.add_edge(t, T, K, 0, 0);
    
    ll minflow = 0;
    for (int i = 0; i < M; ++i)
    {
        ll u, v, c, d; cin >> u >> v >> c >> d;
        u--, v--;
        
        mcf.add_edge(u, v, K - 1, c + d, d);
        mcf.add_edge(S, v, 1, c, 0);
        mcf.add_edge(u, T, 1, 0, 0);
        minflow += 1;
    }
    ll res = mcf.min_cost_flow(S, T, K + minflow);
    cout << res << endl;
    
    return;
}


int main()
{
    while (!is_end)
    {
        solve();
    }
    
    return 0;
}
accuracy: 1
time_ms: 2570
memory_kb: 3608
final_rank: 4

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

using ll = long long;

template<class flow_t = long long, class cost_t = long long>
struct PrimalDual
{
    const cost_t INF;
    
    struct edge
    {
        int to;
        int rev;
        flow_t cap;
        cost_t cost;
        cost_t diff;
    };
    
    int siz;
    vector<vector<edge>> graph;
    vector<cost_t> potential, min_cost;
    vector<int> prev_v, prev_id;
    
    PrimalDual(int _n) : siz(_n), INF(1e18), graph(_n) { }
    
    void add_edge(int from, int to, flow_t cap, cost_t cost, cost_t diff)
    {
        assert(from < siz && to < siz);
        graph[from].emplace_back((edge){to, (int)graph[to].size(), cap, cost, diff});
        graph[to].emplace_back((edge){from, (int)graph[from].size() - 1, 0, -cost + diff, diff});
    }
    
    cost_t min_cost_flow(int s, int t, flow_t f)
    {
        cost_t ret = 0;
        using Pi = pair<cost_t, int>;
        priority_queue<Pi, vector<Pi>, greater<Pi>> pq;
        potential.assign(siz, 0);
        prev_v.assign(siz, -1);
        prev_id.assign(siz, -1);
        
        while (f > 0)
        {
            min_cost.assign(siz, INF);
            pq.emplace(0, s);
            min_cost[s] = 0;
            
            while (!pq.empty())
            {
                auto [cost, v] = pq.top();
                pq.pop();
                
                if (min_cost[v] < cost) continue;
                for (int i = 0; i < graph[v].size(); ++i)
                {
                    auto &e = graph[v][i];
                    cost_t next_cost = min_cost[v] + e.cost + (potential[v] - potential[e.to]);
                    if (e.cap > 0 && min_cost[e.to] > next_cost)
                    {
                        min_cost[e.to] = next_cost;
                        prev_v[e.to] = v;
                        prev_id[e.to] = i;
                        pq.emplace(min_cost[e.to], e.to);
                    }
                }
            }
            
            if (min_cost[t] == INF)
            {
                return -1;
            }
            
            for (int v = 0; v < siz; ++v) potential[v] += min_cost[v];
            flow_t addflow = f;
            for (int v = t; v != s; v = prev_v[v])
            {
                addflow = min(addflow, graph[prev_v[v]][prev_id[v]].cap);
            }
            addflow = 1; // ここ変更した
            f -= addflow;
            ret += addflow * potential[t];
            for (int v = t; v != s; v = prev_v[v])
            {
                auto &e = graph[prev_v[v]][prev_id[v]];
                e.cap -= addflow;
                e.cost += e.diff;
                
                auto &re = graph[e.to][e.rev];
                re.cap += addflow;
                re.cost -= re.diff;
            }
        }
        return ret;
    }
};


bool is_end = false;

void solve()
{
    ll N, M, K; cin >> N >> M >> K;
    if (N == 0)
    {
        is_end = true;
        return;
    }
    
    int S = N, T = N + 1;
    vector<ll> D(N, 0);
    D[0] += K, D[N - 1] -= K;
    ll mincost = 0;
    
    PrimalDual<ll, ll> mcf(T + 1);
    for (int i = 0; i < M; ++i)
    {
        ll u, v, c, d; cin >> u >> v >> c >> d;
        u--, v--;
        
        mcf.add_edge(u, v, K - 1, c + d, d);
        D[u] -= 1;
        D[v] += 1;
        mincost += c;
    }
    int in = 0;
    for (int i = 0; i < N; ++i)
    {
        if (D[i] > 0)
        {
            mcf.add_edge(S, i, D[i], 0, 0);
            in += D[i];
        }
        if (D[i] < 0)
        {
            mcf.add_edge(i, T, -D[i], 0, 0);
        }
    }
    
    ll res = mcf.min_cost_flow(S, T, in);
    
    if (res == -1) cout << res << endl;
    else cout << res + mincost << endl;
    
    return;
}


int main()
{
    while (!is_end)
    {
        solve();
    }
    
    return 0;
}
accuracy: 1
time_ms: 1830
memory_kb: 3604
final_rank: 2

code_snippet: #include <bits/stdc++.h>

#define rep(i, s, n) for (int i = int(s); i < int(n); i++)
#define rrep(i, s, n) for (int i = int(n) - 1; i >= s; i--)
#define all(v) v.begin(), v.end()

using ll = long long;
using ld = long double;
using ull = unsigned long long;

template <class T> bool chmin(T &a, T b) {
    if (a <= b) return false;
    a = b;
    return true;
}

template <class T> bool chmax(T &a, T b) {
    if (a >= b) return false;
    a = b;
    return true;
}

using namespace std;

pair<ll, ll> inv_gcd(ll a, ll b){
    a = a % b;
    if (a == 0) return {b, 0};
    ll s = b, t = a;
    ll m0 = 0, m1 = 1;
    while(t){
        ll u = s/t;
        s -= t*u;
        m0 -= m1*u;
        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b/s;
    return {s,m0};
}

ll inv_mod(ll x, ll m){
    assert(1<=m);
    auto z = inv_gcd(x, m);
    assert(z.first == 1);
    return z.second;
}

vector<ll> pl(ll n){
    vector<ll> ret;
    for (ll i=2; i*i<=n; i++){
        if (n%i == 0){
            while(n%i == 0) n/=i;
            ret.push_back(i);
        }
    }
    if (n>1) ret.push_back(n);
    return ret;
}

vector<ll> div(ll n){
    vector<ll> ret;
    for (ll i=1; i*i<=n; i++){
        if (n%i == 0){
            ret.push_back(i);
            if (i*i != n){
                ret.push_back(n/i);
            }
        }
    }
    sort(all(ret));
    return ret;
}

/*
struct MinCostFlow{
    int n;
    vector<vector<vector<ll>>> g;
    vector<ll> h, dis;
    vector<int> pv, pe;
    MinCostFlow(int v):n(v), g(v), dis(v), pv(v), pe(v){}
    void add_edge(int from, int to, ll cap, ll cost){
        g[from].push_back({to,cap,cost,(int)g[to].size()});
        g[to].push_back({from,0,-cost,(int)g[from].size()-1});
    }
    ll flow(int s, int t, ll f){
        ll res = 0;
        h.assign(n, 0);
        using Q = pair<ll,int>;
        while(f>0){
            priority_queue<Q,vector<Q>,greater<Q>> que;
            dis.assign(n, LLONG_MAX);
            dis[s] = 0;
            que.push({0,s});
            while(que.size()){
                Q q=que.top();
                int v = q.second;
                que.pop();
                if (dis[v]<q.first)continue;
                rep(i,0,g[v].size()){
                    auto edge=g[v][i];
                    int to=edge[0];
                    ll cap=edge[1], cost=edge[2];
                    if(cap>0 and dis[to]>dis[v]+cost+h[v]-h[to]){
                        dis[to]=dis[v]+cost+h[v]-h[to];
                        pv[to]=v;
                        pe[to]=i;
                        que.push({dis[to],to});
                    }
                }
            }
            if(dis[t]==LLONG_MAX)return -1;
            rep(i,0,n)h[i]+=dis[i];
            ll d=f;
            for(int i=t;i!=s;i=pv[i]){
                d=min(d,g[pv[i]][pe[i]][1]);
            }
            f-=d;
            res+=d*h[t];
            for (int i=t;i!=s;i=pv[i]){
                auto& edge=g[pv[i]][pe[i]];
                edge[1]-=d;
                g[i][edge[3]][1]+=d;
            }
        }
        return res;
    }
};
*/

/**/
struct MinCostFlow{
    int n;
    vector<vector<vector<ll>>> g;
    vector<ll> h, dis;
    vector<int> pv, pe;
    MinCostFlow(int v):n(v), g(v), dis(v), pv(v), pe(v){}
    void add_edge(int from, int to, ll cap, ll cost, ll cost2){
        g[from].push_back({to,cap,cost,(int)g[to].size(),cost2});
        g[to].push_back({from,0,-cost+cost2,(int)g[from].size()-1,cost2});
    }
    ll flow(int s, int t, ll f){
        ll res = 0;
        h.assign(n, 0);
        using Q = pair<ll,int>;
        while(f>0){
            priority_queue<Q,vector<Q>,greater<Q>> que;
            dis.assign(n, LLONG_MAX);
            dis[s] = 0;
            que.push({0,s});
            while(que.size()){
                Q q=que.top();
                int v = q.second;
                que.pop();
                if (dis[v]<q.first)continue;
                rep(i,0,g[v].size()){
                    auto edge=g[v][i];
                    int to=edge[0];
                    ll cap=edge[1], cost=edge[2];
                    if(cap>0 and dis[to]>dis[v]+cost+h[v]-h[to]){
                        dis[to]=dis[v]+cost+h[v]-h[to];
                        pv[to]=v;
                        pe[to]=i;
                        que.push({dis[to],to});
                    }
                }
            }
            if(dis[t]==LLONG_MAX)return -1;
            rep(i,0,n)h[i]+=dis[i];
            f-=1;
            res+=h[t];
            for (int i=t;i!=s;i=pv[i]){
                auto& edge=g[pv[i]][pe[i]];
                edge[1]-=1;
                edge[2]+=edge[4];
                g[i][edge[3]][1]+=1;
                g[i][edge[3]][2]-=g[i][edge[3]][4];
            }
        }
        return res;
    }
};

void solve(int n, int m, int k){
    MinCostFlow mcf(n+2);
    ll geta = 0;
    rep(i,0,m){
        int s,t;
        ll c,d;
        cin >> s >> t >> c >> d;
        s--; t--;
        mcf.add_edge(s,  t,k,c+d,d);
        mcf.add_edge(s,n+1,1,  0,0);
        mcf.add_edge(n,  t,1,  0,0);
        geta+=c;
    }
    mcf.add_edge(n-1, n+1, k, 0, 0);
    mcf.add_edge(n, 0, k, 0, 0);
    ll ans = mcf.flow(n,n+1,k+m);
    if (ans == -1){
        cout << -1 << endl;
    }else{
        cout<< geta+ans<<endl;
    }
}

int main() {
    while(true){
        int n,m,k;cin>>n>>m>>k;
        if(n==0)break;
        solve(n,m,k);
    }
}
accuracy: 1
time_ms: 7510
memory_kb: 3700
final_rank: 11

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

template<typename T>
struct WeightedEdge{
  WeightedEdge()=default;
  WeightedEdge(int from,int to,T weight):from(from),to(to),weight(weight){}
  int from,to;
  T weight;
};

template<typename T>
struct WeightedGraph{
  int n;
  using weight_type=T;
  using edge_type=WeightedEdge<T>;
  vector<edge_type> edges;
protected:
  vector<int> in_deg;
  bool prepared;
  class OutgoingEdges{
    WeightedGraph* g;
    int l,r;
  public:
    OutgoingEdges(WeightedGraph* g,int l,int r):g(g),l(l),r(r){}
    edge_type* begin(){ return &(g->edges[l]); }
    edge_type* end(){ return &(g->edges[r]); }
    edge_type& operator[](int i){ return g->edges[l+i]; }
    int size()const{ return r-l; }
  };
public:
  OutgoingEdges operator[](int v){
    assert(prepared);
    return { this,in_deg[v],in_deg[v+1] };
  }

  bool is_prepared()const{ return prepared; }

  WeightedGraph():n(0),in_deg(1,0),prepared(false){}
  WeightedGraph(int n):n(n),in_deg(n+1,0),prepared(false){}
  WeightedGraph(int n,int m,bool directed=false,int indexed=1):
    n(n),in_deg(n+1,0),prepared(false){ scan(m,directed,indexed); }

  void resize(int n){n=n;}

  void add_arc(int from,int to,T weight){
    assert(!prepared);
    assert(0<=from and from<n and 0<=to and to<n);
    edges.emplace_back(from,to,weight);
    in_deg[from+1]++;
  }
  void add_edge(int u,int v,T weight){
    add_arc(u,v,weight);
    add_arc(v,u,weight);
  }
  void add_arc(const edge_type&e){
    add_arc(e.from,e.to,e.weight);
  }
  void add_edge(const edge_type&e){
    add_edge(e.from,e.to,e.weight);
  }

  void scan(int m,bool directed=false,int indexed=1){
    edges.reserve(directed?m:2*m);
    while(m--){
      int u,v;cin>>u>>v;u-=indexed;v-=indexed;
      T weight;cin>>weight;
      if(directed)add_arc(u,v,weight);
      else add_edge(u,v,weight);
    }
    build();
  }

  void build(){
    assert(!prepared);prepared=true;
    for(int v=0;v<n;v++)in_deg[v+1]+=in_deg[v];
    vector<edge_type> new_edges(in_deg.back());
    auto counter=in_deg;
    for(auto&&e:edges)new_edges[ counter[e.from]++ ]=e;
    edges=new_edges;
  }

  void graph_debug()const{
  #ifndef __LOCAL
    return;
  #endif
    assert(prepared);
    for(int from=0;from<n;from++){
      cerr<<from<<";";
      for(int i=in_deg[from];i<in_deg[from+1];i++)
        cerr<<"("<<edges[i].to<<","<<edges[i].weight<<")";
      cerr<<"\n";
    }
  }
};

// 辺の重みが流量に対して単調増加な関数
#define REP_(i,n) for(int i=0;i<(n);i++)
template<typename TC>
class NondecreasingMCF{
  using F = function<TC(int)>;
  struct EdgeInfo{
    int cap,flow,rev;
    bool reverse_edge;
    F cost_func;
    
    EdgeInfo()=default;
    EdgeInfo(int cap,F cost_func,int rev,bool reverse_edge):
      cap(cap),cost_func(cost_func),rev(rev),reverse_edge(reverse_edge),flow(0){}
    
    TC cost()const{
      if(!reverse_edge)return cost_func(flow);
      return -cost_func(cap-1);
    }
  };
  int n;
  WeightedGraph< EdgeInfo > G;
  vector<TC> potential,dist;
  static constexpr TC INF=1e30;//numeric_limits<TC>::max()/2;
  vector<pair<int,int>> pre; // pre[v]=[u,i] : G[u][i] で v に来た
  vector<int> in_deg,out_deg;
  priority_queue< pair<TC,int>,vector<pair<TC,int>>,greater<pair<TC,int>>> que;
  bool negative=false;//負辺存在するか

  template<typename T>
  bool chmin(T&a,const T&b){
    return (a>b and (a=b,true));
  }
  bool SP_update(int from,int edge_id){
    const auto&e=G[from][edge_id];
    if((e.weight).cap==0)return false;
    if(chmin(dist[e.to],dist[from]+(e.weight).cost()+potential[from]-potential[e.to])){
      pre[e.to]={from,edge_id};
      return true;
    }
    return false;
  }

  void dijkstra(int s){//dist[i]:sから残余グラフで辺の重みによるiへの最短路 となるようにdistを作る
    fill(dist.begin(),dist.end(),INF);
    dist[s]=0;
    que.emplace(0,s);
    while(que.size()){
      const auto [now,v]=que.top();que.pop();
      if(dist[v]<now)continue;
      REP_(i,G[v].size())
        if(SP_update(v,i))
          que.emplace(dist[G[v][i].to],G[v][i].to);
    }
  }

  void DAG(int s){
    negative=false;
    fill(dist.begin(),dist.end(),INF);
    dist[s]=0;
    queue<int> que;
    REP_(i,n)if(!in_deg[i])que.push(i);
    while(que.size()){
      int v=que.front();que.pop();
      REP_(i,G[v].size()){
        SP_update(v,i);
        if(!--in_deg[G[v][i].to])que.push(G[v][i].to);
      }
    }
  }
public:
  NondecreasingMCF(){}
  NondecreasingMCF(int n_):n(n_),G(n_),potential(n_,0),dist(n_),pre(n_),in_deg(n_,0),out_deg(n_,0),negative(false){}
  
  void add_arc(int u,int v,int cap,F cost_func){
    G.add_arc(u,v,{cap,cost_func,out_deg[v],false});
    G.add_arc(v,u,{0,cost_func,out_deg[u],true});
    out_deg[v]++;out_deg[u]++;
    if(cap>0){
      in_deg[v]++;
      negative|=cost_func(0)<0;
    }
  }

  pair<TC,bool> flow(int s,int t,int f){
    if(!G.is_prepared())G.build();
    TC res=0;
    fill(potential.begin(),potential.end(),0);
    for(int i=0;i<f;i++){
      if(negative)DAG(s);
      else dijkstra(s);
      if(dist[t]==INF)return make_pair(res,false);
      REP_(v,n)if(dist[v]!=INF)potential[v]+=dist[v];
      res+=potential[t];
      for(int v=t;v!=s;v=pre[v].first){
        auto& w=G[pre[v].first][pre[v].second].weight;
        w.cap--;w.flow++;
        auto& r=G[v][w.rev].weight;
        r.cap++;r.flow--;
      }
    }
    return make_pair(res,true);
  }
};
#undef REP_
using ll=long long;
const __int128 LINF=1e20;

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int n,m,k;
  while(cin>>n>>m>>k,n){
    NondecreasingMCF<__int128> fl(n);
    for(int i=0;i<m;i++){
      ll s,t,c,d;cin>>s>>t>>c>>d;s--;t--;
      fl.add_arc(s,t,k,[c,d](int x){
        return c + ( x ? x*d : -LINF );
      });
    }
    auto [ans,ok]=fl.flow(0,n-1,k);
    ans += LINF*m;
    cout<< (ans<LINF?ll(ans):-1LL) <<"\n";
  }
}
accuracy: 1
time_ms: 2500
memory_kb: 3636
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <limits>

using namespace std;

using LL = long long;

struct min_cost_flow{
	typedef LL cap_type;
	typedef LL cost_type;
	struct edge{
		int to;
		cap_type cap;
		cost_type cost;
		cost_type delta;
		int rev;
		
		edge(int t, cap_type cp, cost_type cs, cost_type dt, int r)
		: to(t), cap(cp), cost(cs), delta(dt), rev(r) {}
	};

	vector<vector<edge> > G;

	min_cost_flow(){}
	min_cost_flow(int m) : G(m) {}
	
	size_t size() const{
		return G.size();
	}

	void add_edge(int from, int to, cap_type cap, cost_type cost, cost_type delta){
		if(from == to){ return; }
		int sf = G[from].size(), st = G[to].size();
/*
		G[from].push_back(edge(to, cap, cost, st));
		G[to].push_back(edge(from, cap_type(0), -cost, sf));
*/
		G[from].push_back(edge(to, cap, cost + delta, delta, st));
		G[to].push_back(edge(from, cap_type(0), -cost, delta, sf));
	}

	cost_type calc(int s, int t, cap_type f, cap_type &f_result){
		typedef pair<cost_type,int> P;

		cost_type res = 0;
		const cost_type INF = numeric_limits<cost_type>::max();
		const int V = G.size();

		vector<cost_type> dist;
		vector<cost_type> h(V, cost_type(0));
		vector<int> prevv(V), preve(V);

		cap_type f0 = f;
		while(f > 0){
			priority_queue<P,vector<P>,greater<P> > que;
			dist.assign(V, INF);
			dist[s] = cost_type(0);
			que.push(P(cost_type(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 < (int)G[v].size(); ++i){
					edge &e = G[v][i];
					cost_type tmp = dist[v] + e.cost + h[v] - h[e.to];
					if(e.cap > 0 && dist[e.to] > tmp){
						dist[e.to] = tmp;
						prevv[e.to] = v;
						preve[e.to] = i;
						que.push(P(dist[e.to], e.to));
					}
				}
			}

			if(dist[t] == INF){
				break;
			}
			
			for(int v = 0; v < V; ++v){
				h[v] += dist[v];
			}

/*
			cap_type 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;
			}
*/
			--f;
			res += h[t];
			for(int v = t; v != s; v = prevv[v]){
				edge &e = G[prevv[v]][preve[v]];
				--e.cap;
				e.cost += e.delta;
				edge &r = G[v][e.rev];
				++r.cap;
				r.cost -= r.delta;
			}
		}
		
		f_result = f0 - f;
		
		return res;
	}
};

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

	int n, m, k;
	while(cin >> n >> m >> k && n){
		min_cost_flow mcf(n + 10);
		int spsrc = n + 7;
		int spsnk = spsrc + 1;
		
		mcf.add_edge(spsrc, 1, k, 0, 0);
		mcf.add_edge(n, spsnk, k, 0, 0);

		LL ans = 0;
		for(int i = 0; i < m; ++i){
			LL a, b, c, d;
			cin >> a >> b >> c >> d;
			
			ans += c;
			mcf.add_edge(a, b, k, c, d);
			mcf.add_edge(a, spsnk, 1, 0, 0);
			mcf.add_edge(spsrc, b, 1, 0, 0);
		}
		
		LL fres = 0;
		ans += mcf.calc(spsrc, spsnk, m + k, fres);
		if(fres < m + k){
			ans = -1;
		}
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 2640
memory_kb: 3640
final_rank: 7