Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; i++)
- #define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; i--)
- #define REP(i,a) for(int i=0,_a=(a); i<_a; i++)
- #define EACH(it,a) for(__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
- #define DEBUG(x) { cout << #x << " = "; cout << (x) << endl; }
- #define PR(a,n) { cout << #a << " = "; FOR(_,1,n) cout << a[_] << ' '; cout << endl; }
- #define PR0(a,n) { cout << #a << " = "; REP(_,n) cout << a[_] << ' '; cout << endl; }
- #define sqr(x) ((x) * (x))
- using namespace std;
- #define F_INF 1000111000LL
- #define C_INF 1000111000LL
- template<class Flow = long long, class Cost = long long>
- struct MinCostFlow {
- int V, E;
- vector<Flow> cap;
- vector<Cost> cost;
- vector<int> to, prev;
- vector<Cost> dist, pot;
- vector<int> last, path, used;
- priority_queue< pair<Cost, int> > q;
- MinCostFlow(int V, int E) : V(V), E(0), cap(E*2,0), cost(E*2,0), to(E*2,0), prev(E*2,0),
- dist(V,0), pot(V,0), last(V, -1), path(V,0), used(V,0) {}
- int addEdge(int x, int y, Flow f, Cost c) {
- cap[E] = f; cost[E] = c; to[E] = y; prev[E] = last[x]; last[x] = E; E++;
- cap[E] = 0; cost[E] = -c; to[E] = x; prev[E] = last[y]; last[y] = E; E++;
- return E - 2;
- }
- pair<Flow, Cost> search(int s, int t) {
- Flow ansf = 0; Cost ansc = 0;
- REP(i,V) used[i] = false;
- REP(i,V) dist[i] = C_INF;
- dist[s] = 0; path[s] = -1; q.push(make_pair(0, s));
- while (!q.empty()) {
- int x = q.top().second; q.pop();
- if (used[x]) continue; used[x] = true;
- for(int e = last[x]; e >= 0; e = prev[e]) if (cap[e] > 0) {
- Cost tmp = dist[x] + cost[e] + pot[x] - pot[to[e]];
- if (tmp < dist[to[e]] && !used[to[e]]) {
- dist[to[e]] = tmp;
- path[to[e]] = e;
- q.push(make_pair(-dist[to[e]], to[e]));
- }
- }
- }
- REP(i,V) pot[i] += dist[i];
- if (used[t]) {
- ansf = F_INF;
- for(int e=path[t]; e >= 0; e=path[to[e^1]]) ansf = min(ansf, cap[e]);
- for(int e=path[t]; e >= 0; e=path[to[e^1]]) { ansc += cost[e] * ansf; cap[e] -= ansf; cap[e^1] += ansf; }
- }
- return make_pair(ansf, ansc);
- }
- pair<Flow, Cost> minCostFlow(int s, int t) {
- Flow ansf = 0; Cost ansc = 0;
- while (1) {
- pair<Flow, Cost> p = search(s, t);
- if (!used[t]) break;
- ansf += p.first; ansc += p.second;
- }
- return make_pair(ansf, ansc);
- }
- };
- const int MN = 111*111*2;
- long long f[111][111], c[111][111];
- int id_u[MN], id_v[MN], edges[MN];
- int main() {
- int n, m, k, s, t;
- while (cin >> n >> m >> k >> s >> t) {
- MinCostFlow<long long, long long> mcf(n+1, m*2+2);
- mcf.addEdge(0, s, k, 0);
- memset(f, 0, sizeof f);
- FOR(i,1,m) {
- int u, v;
- cin >> u >> v;
- cin >> c[u][v] >> f[u][v];
- c[v][u] = c[u][v]; f[v][u] = f[u][v];
- }
- m = 0;
- FOR(i,1,n) FOR(j,i+1,n) if (f[i][j]) {
- edges[++m] = mcf.addEdge(i, j, f[i][j], c[i][j]); id_u[m] = i; id_v[m] = j;
- edges[++m] = mcf.addEdge(j, i, f[i][j], c[i][j]); id_u[m] = j; id_v[m] = i;
- }
- pair<long long, long long> res = mcf.minCostFlow(0, t);
- if (res.first < k) {
- cout << -1 << endl;
- continue;
- }
- cout << res.second << endl;
- FOR(i,1,m/2) {
- int u = id_u[i], v = id_v[i];
- int f_xuoi = f[u][v] - mcf.cap[edges[i*2-1]];
- int f_nguoc = f[v][u] - mcf.cap[edges[i*2]];
- int t = min(f_xuoi, f_nguoc);
- f_xuoi -= t;
- f_nguoc -= t;
- if (f_xuoi > 0) {
- cout << id_u[i*2-1] << ' ' << id_v[i*2-1] << ' ' << f_xuoi << endl;
- }
- if (f_nguoc > 0) {
- cout << id_u[i*2] << ' ' << id_v[i*2] << ' ' << f_nguoc << endl;
- }
- }
- cout << "0 0 0" << endl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement