Pagini recente » Borderou de evaluare (job #1847161) | Borderou de evaluare (job #1845902) | Cod sursa (job #2882298)
#include <bits/stdc++.h>
using namespace std;
ifstream f("maxflow.in");
ofstream g("maxflow.out");
// #define f cin
// #define g cout
const int nmax = 1003;
struct edge
{
int to, capacity, flow, residual;
int remaining() const { return capacity - flow; }
};
vector<edge> v[nmax];
int visited[nmax], token = 1;
int level[nmax], nexti[nmax];
int n, source, sink;
void get_graph();
int max_flow();
bool bfs();
int dfs(int, int);
int32_t main()
{
get_graph();
g << max_flow();
return 0;
}
void get_graph()
{
int m;
f >> n >> m;
source = 1;
sink = n;
edge ax1, ax2;
for (int x, y, c; m; m--)
{
f >> x >> y >> c;
ax1.to = y;
ax1.capacity = c;
ax1.flow = 0;
ax1.residual = v[y].size();
ax2.to = x;
ax2.capacity = 0;
ax2.flow = 0;
ax2.residual = v[x].size();
v[x].push_back(ax1);
v[y].push_back(ax2);
}
}
int max_flow()
{
int rez = 0;
while (bfs())
{
token++;
memset(nexti, 0, sizeof nexti);
for (int mnm = dfs(source, INT_MAX); mnm; mnm = dfs(source, INT_MAX))
rez += mnm;
}
return rez;
}
bool bfs()
{
static queue<int> q;
visited[source] = token;
q.push(source);
level[source] = 1;
for (int ac; !q.empty();)
{
ac = q.front();
q.pop();
for (const auto &i : v[ac])
if (i.remaining() > 0 && visited[i.to] != token)
{
level[i.to] = level[ac] + 1;
visited[i.to] = token;
q.push(i.to);
}
}
return (visited[sink] == token);
}
int dfs(int ac, int minim)
{
if (ac == sink)
return minim;
for (edge ne; nexti[ac] < (int)v[ac].size(); nexti[ac]++)
{
ne = v[ac][nexti[ac]];
if (level[ne.to] == 1 + level[ac] && ne.remaining() > 0)
{
int ax = dfs(ne.to, min(minim, ne.remaining()));
if (ax > 0)
{
v[ac][nexti[ac]].flow += ax;
v[ne.to][v[ac][nexti[ac]].residual].flow -= ax;
nexti[ac]++;
return ax;
}
}
}
return 0;
}