Cod sursa(job #2664828)

Utilizator BogdanTicuTicu Bogdan Valeriu BogdanTicu Data 29 octombrie 2020 15:42:01
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <bits/stdc++.h>

using namespace std;

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

int n,m,sursa,destination;
vector<int> graf[355];
int capacity[355][355],flux[355][355],previous[355],cost[355][355];
bool viz[355];
int d_old[355],d[355],d_new[355];

const int INF=INT_MAX-1000;
priority_queue<pair<int,int>, vector<pair<int,int>>,greater<pair<int,int>> >pq;
void bellmanford()
{
	for(int i=1;i<=n;i++)
		d_old[i]=INF;
	viz[sursa]=1;
	queue<int> q;
	q.push(sursa);
	d_old[sursa]=0;

	while(!q.empty())
	{
		int node=q.front();
		q.pop();
		viz[node]=0;
		for(auto x:graf[node])
		{
			if(capacity[node][x]>flux[node][x])
			{
				if(d_old[x]>d_old[node]+cost[node][x])
				{
					d_old[x]=d_old[node]+cost[node][x];
					if(!viz[x])
					{
						q.push(x);
						viz[x]=1;
					}
				}
			}
		}
	}
}

bool dijkstra()
{
	for(int i=1;i<=n;i++)
		d[i]=INF;
	pq.push({0,sursa});
	d[sursa]=0;
	d_new[sursa]=0;
	while(!pq.empty())
	{
	//	out<<"In dijkstra in while"<<"\n";
		int node=pq.top().second;
		int cst=pq.top().first;
		pq.pop();
		if(d[node]!=cst)
			continue;
		
		for(auto x:graf[node])
		{
			if(flux[node][x]<capacity[node][x])
			{
				int distanta=d[node]+cost[node][x]+d_old[node]-d_old[x];
				if(distanta<d[x])
				{
					d[x]=distanta;
					d_new[x]=d_new[node]+cost[node][x];
					previous[x]=node;
					pq.push({d[x],x});
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
		d_old[i]=d_new[i];
	return (d[destination]!=INF);
}


int main()
{
	in>>n>>m>>sursa>>destination;
	for(int i=1;i<=m;i++)
	{
		int x,y,c,z;
		in>>x>>y>>c>>z;
		graf[x].push_back(y);
		graf[y].push_back(x);

		capacity[x][y]=c;
		
		cost[x][y]=z;
		cost[y][x]=-z;
	}

	int ans=0;
	bellmanford();
	while(dijkstra())
	{
			int minn=INF;
			for(int i=destination;i!=sursa;i=previous[i])
				minn=min(minn,capacity[previous[i]][i]-flux[previous[i]][i]);
	//		out<<"Minim este egal cu "<<minn<<"\n";				
			for(int i=destination;i!=sursa;i=previous[i])
			{
				flux[previous[i]][i]+=minn;
				flux[i][previous[i]]-=minn;
			}
			ans+=minn*d_new[destination];
	}
	out<<ans;
	return 0;
}