Cod sursa(job #2961906)

Utilizator NicuDirvaDirva Nicolae NicuDirva Data 7 ianuarie 2023 12:59:22
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.67 kb
#include <fstream>
#include <vector>
#include <queue>

#define inf 1e9

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");


int n, m, s, d;

vector<int> gr[355];

int cost[355][355];
int capacitate[355][355];
int flux[355][355];

int DP[355][2];
int dp[355];
int tata[355];

queue<int> q;
int viz[355];

void norm()
{
	for(int i=1;i<= n;i++)
    {
		DP[i][0] = inf;
    }

	DP[s][0] = 0;
	q.push(s);

	while(!q.empty())
    {
		int node = q.front();
		q.pop();
		viz[node] = 0;

		for(auto& vecin : gr[node])
		{
			if (capacitate[node][vecin] && DP[vecin][0] > DP[node][0] + cost[node][vecin])
            {
				DP[vecin][0] = DP[node][0] + cost[node][vecin];
				if (!viz[vecin])
				{
					q.push(vecin);
					viz[vecin] = 1;
				}
			}
		}
	}
}

class cmp
{
public:
	bool operator () (pair < int, int > a, pair < int, int > b)
	{
		return a.first > b.first;
	}
};

priority_queue < pair < int, int >, vector < pair < int, int > > , cmp > pq;

int fluxmax()
{

	for(int i=1;i<=n;i++)
    {
		dp[i] = inf;
		tata[i] = 0;
	}
	dp[s] = 0;
	tata[s] = s;
	pq.push({0 ,s});

	int ok = 0;

	while(!pq.empty())
    {
		pair < int, int > aux = pq.top();
        int node = aux.second, val = aux.first;
		pq.pop();

		if(node == d)
        {
			ok = 1;
			continue;
		}
		if(val != dp[node])
		{
			continue;
		}

		for(auto& vecin : gr[node])
        {
			if(capacitate[node][vecin] > flux[node][vecin])
			{
				int now = val + cost[node][vecin] + DP[node][0] - DP[vecin][0];

				if(dp[vecin] > now)
                {
					dp[vecin] = now;
					tata[vecin] = node;
					DP[vecin][1] = DP[node][1] + cost[node][vecin];
					pq.push({ dp[vecin] , vecin });
				}
			}
		}

	}

	for(int i=1;i<=n;i++)
    {
		DP[i][0] = DP[i][1];
	}

	return ok;

}

int main()
{
    int w,x,y,z;

	fin>>n>>m>>s>>d;

	for(int i=0;i<m;i++)
    {
		fin>>w>>x>>y>>z;
		gr[w].push_back(x);
		gr[x].push_back(w);
		capacitate[w][x] += y;
		cost[w][x] += z;
		cost[x][w] -= z;
	}

	norm();

	int ans = 0;

	while(fluxmax())
    {
		int nod_curent = d;
		int MIN = inf;
		while(nod_curent != s)
        {
			MIN = min(MIN, capacitate[tata[nod_curent]][nod_curent] - flux[tata[nod_curent]][nod_curent]);
			nod_curent = tata[nod_curent];
		}

		nod_curent = d;

		while(nod_curent != s)
		{
			ans += MIN * cost[tata[nod_curent]][nod_curent];
			flux[tata[nod_curent]][nod_curent] += MIN;
			flux[nod_curent][tata[nod_curent]] -= MIN;
			nod_curent = tata[nod_curent];
		}

	}

	fout<<ans;

	fin.close();
	fout.close();

	//Complexitate: O(n*m*log(n))
	return 0;
}