Cod sursa(job #2807894)

Utilizator vladth11Vlad Haivas vladth11 Data 24 noiembrie 2021 12:27:58
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.35 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <long double, pii> muchie;

const ll NMAX = 351;
const ll VMAX = 21;
const ll INF = (1LL << 55);
const ll MOD = 998244353;
const ll BLOCK = 318;
const ll base = 31;
const ll nr_of_bits = 30;

vector <int> v[NMAX];

int cnt = 0, s, d, n, viz[NMAX];
int dist[NMAX], last[NMAX], distt[NMAX], distn[NMAX];
int cap[NMAX][NMAX];
int costt[NMAX][NMAX];

void addEdge(int a, int b, int c, int cost) {
    costt[a][b] = cost;
    cap[a][b] = c;
    v[a].push_back(b);
    costt[b][a] = -cost;
    v[b].push_back(a);
}

int invers(int x) {
    if(x % 2)
        return (x + 1);
    return (x - 1);
}

void bellman() {
    for(int i = 1; i <= n; i++) {
        viz[i] = 0, distt[i] = 2e9;
        last[i] = 0;
    }
    queue <int> pq;
    pq.push(s);
    viz[s] = 1;
    distt[s] = 0;
    while(pq.size()) {
        int node = pq.front();
        pq.pop();
        viz[node] = 0;
        for(auto x : v[node]) {
            if(!cap[node][x])
                continue;
            int to = x;
            int cost = costt[node][x];
            if(distt[node] + cost < distt[to]) {
                distt[to] = distt[node] + cost;
                last[to] = x;
                if(!viz[to]) {
                    pq.push(to);
                    viz[to] = 1;
                }
            }
        }
    }
}

bool Dijkstra(){
    for(ll i = 1; i <= n; i++){
        viz[i] = 0, dist[i] = 2e9, distn[i] = 2e9;
        last[i] = 0;
    }
    priority_queue <pii> pq;
    pq.push({0, s});
    dist[s] = 0;
    distn[s] = 0;
    while(pq.size()){
        while(pq.size() && viz[pq.top().second])
            pq.pop();
        if(!pq.size())
            continue;
        ll node = pq.top().second;
        pq.pop();
        viz[node] = 1;
        for(auto x : v[node]){
            if(!cap[node][x])
                continue;
            ll to = x;
            ll cost = costt[node][x] + distt[node] - distt[to];
            if(dist[node] + cost < dist[to]){
                dist[to] = dist[node] + cost;
                distn[to] = distn[node] + costt[node][x];
                pq.push({-dist[to], to});
                last[to] = node;
            }
        }
    }
    for(int i = 1; i <= n; i++)
        distt[i] = distn[i];
    if(viz[d])
        return 1;
    return 0;
}
class InParser {
private:
	FILE *fin;
	char *buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}

	InParser& operator >> (int &n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}

	InParser& operator >> (long long &n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
};

ll flow() {
    ll sol = 0;
    while(Dijkstra()) {
        int minim = 2e9;
        int node = last[d];
        int l = d;
        while(node != 0) {
            minim = min(1LL * minim, 1LL * cap[node][l]);
            l = node;
            node = last[node];
        }
        sol += 1LL * minim * distt[d];
        node = last[d];
        l = d;
        while(node != 0) {
            cap[node][l] -= minim;
            cap[l][node] += minim;
            l = node;
            node = last[node];
        }
    }
    return sol;
}

int main() {
    InParser cin("fmcm.in");
    ofstream cout("fmcm.out");
    int m, i;
    cin >> n >> m >> s >> d;
    for(i = 1; i <= m; i++) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        addEdge(a, b, c, d);
    }
    bellman();
    cout << flow();
    return 0;
}