Cod sursa(job #1735992)

Utilizator theo.stoicanTheodor Stoican theo.stoican Data 31 iulie 2016 20:13:10
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.06 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdio>
//#include <priority_queue>
#include <climits>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cassert>
#include <bits/stdc++.h>

using namespace std;

vector<int> d;
vector<int> real_d;
vector<int> p;
vector<int> old_d;
vector<bool> inQ;
queue<int> bellmanq;

vector<vector<int> > graph;
int n,m, src, dst;
int flux;
int fluxCost;
int C[355][355];
int Cost[355][355];

priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;

inline bool dijkstra(int source, int dest)
{
	d.resize(n+1, INT_MAX);	
	fill(d.begin(), d.end(), INT_MAX);
	d[source] = 0;
	real_d[source] = 0;
	q.push(make_pair(d[source], source));
	for (; !q.empty(); )
	{
		int cost = q.top().first;
		int node = q.top().second;
		q.pop();
		//am modificat costul pana la node
		if (d[node] != cost)
			continue;
		for (int i = 0; i < graph[node].size(); i++)
		{
			if (C[node][graph[node][i]])
			{
				int new_d = d[node] + Cost[node][graph[node][i]]+ old_d[node] - old_d[graph[node][i]];
			//	cout<<new_d<<" ";
			//	cout<<d[graph[node][i]]<<endl;
				if (new_d < d[graph[node][i]])
				{
					d[graph[node][i]] = new_d;
					real_d[graph[node][i]] = real_d[node] + Cost[node][graph[node][i]];
					p[graph[node][i]] = node;
			//		cout<<p[graph[node][i]]<<endl;
					q.push(make_pair(d[graph[node][i]], graph[node][i]));
				}
			}
		}
	}
	copy(real_d.begin(), real_d.end(), old_d.begin());
	if (d[dest] == INT_MAX)
		return false;
	int mmin = INT_MAX;
	int curCost = 0;

	//for (int i = 1; i<= n; i++)
	//	cout<<p[i]<<" ";
	//cout<<endl;
	for (int aux = dest; aux != source; aux = p[aux])
	{
		//cout<<aux<<endl;
		mmin = min (mmin, C[p[aux]][aux]);
		curCost += Cost[p[aux]][aux];
	}	

	flux += mmin;
	fluxCost += mmin * real_d[dest];
	for (int aux = dest; aux != source; aux = p[aux])
	{
		C[p[aux]][aux] -= mmin;
		C[aux][p[aux]] += mmin;
	}

	return true;
}

inline bool bellmanFord(int source, int dest)
{
	old_d.resize(n+1, INT_MAX);
	fill(old_d.begin(), old_d.end(),INT_MAX);
	old_d[source] = 0;
	for (bellmanq.push(source), inQ[source] = true; !bellmanq.empty(); bellmanq.pop())
	{
		int node = bellmanq.front();
		inQ[node] = false;
		for (std::vector<int>::iterator	 it = graph[node].begin(); it != graph[node].end(); it++)
		{
			if (C[node][*it])
			{
				if (old_d[node] + Cost[node][*it] >= old_d[*it])
					continue;
				old_d[*it] = old_d[node] + Cost[node][*it];
				if (inQ[*it])
					continue;
				inQ[*it] = true;
				bellmanq.push(*it);
			}
		}
	}
	if (old_d[dest] == INT_MAX)
		return false;
	return true;
}

int main()
{
	int x,y,c,z;
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	cin>>n>>m>>src>>dst;
	graph.resize(n+1);
	for (int i = 1; i <= m; i++)
	{
		cin>>x>>y>>c>>z;
		graph[x].push_back(y);
		graph[y].push_back(x);
		C[x][y] = c;
		Cost[x][y] = z;
		Cost[y][x] = -z;
	}

	d.resize(n+1);
	real_d.resize(n+1);
	p.resize(n+1);
	old_d.resize(n+1);
	inQ.resize(n+1);

	flux = 0;
	fluxCost = 0;
	bellmanFord(src, dst);
	for (; dijkstra(src, dst) ;);
	cout<<fluxCost<<"\n";
	return 0;
}