Cod sursa(job #2651300)

Utilizator ardutgamerAndrei Bancila ardutgamer Data 22 septembrie 2020 10:12:41
Problema Flux maxim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <climits>
#include <fstream>

using namespace std;

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

struct edge
{
	int v;
	int flow;
	int cap;
	int rev;
};

class graph
{
	int n;
	int* dist;
	vector<edge> *g;
public:
	graph(int n)
	{
		this->n = n;
		g = new vector<edge>[n + 5];
		dist = new int[n + 5];
	}
	void addEdge(int x, int y, int c)
	{
		g[x].push_back(edge{ y,0,c,(int)g[y].size() });
		g[y].push_back(edge{ x,0,0,(int)g[x].size() });
	}

	int bfs(int s, int t);
	int sendFlow(int u, int flow, int t, int start[]);
	int Dinic(int s, int t);
};

int graph::bfs(int s, int t)
{
	for (int i = 1; i <= n; i++)
		dist[i] = -1;
	dist[s] = 0;
	queue<int>q;
	q.push(s);
	while (!q.empty())
	{
		int u = q.front();
		q.pop();
		for (vector<edge>::iterator it = g[u].begin(); it != g[u].end(); it++)
		{
			edge& e = *it;
			if (dist[e.v] == -1 && e.flow < e.cap)
			{
				dist[e.v] = dist[u] + 1;
				q.push(e.v);
			}
		}
	}
	return (dist[t] != -1);
}

int graph::sendFlow(int u, int flow, int t, int start[])
{
	if (u == t)
		return flow;
	for (; start[u] < g[u].size(); start[u]++)
	{
		edge& e = g[u][start[u]];
		if (dist[e.v] == dist[u] + 1 && e.flow < e.cap)
		{
			int curr_flow = min(flow, e.cap - e.flow);
			int temp_flow = sendFlow(e.v, curr_flow, t, start);
			if (temp_flow > 0)
			{
				e.flow += temp_flow;
				g[e.v][e.rev].flow -= temp_flow;
				return temp_flow;
			}
		}
	}
	return 0;
}

int graph::Dinic(int s, int t)
{
	int maxFlow = 0;
	while (bfs(s, t))
	{
		int* start = new int[n + 5];
		while (int flow = sendFlow(s, INT_MAX, t, start))
			maxFlow += flow;
	}
	return maxFlow;
}

void solve()
{
    int n, m;
    fin >> n >> m;
    graph g(n);
    while(m--)
    {
        int x,y,c;
        fin >> x >> y >> c;
        g.addEdge(x,y,c);
    }
    fout << g.Dinic(1,n) << "\n";
}

int main()
{
    solve();
	return 0;
}