Pagini recente » Cod sursa (job #2452884) | Cod sursa (job #1258946) | Cod sursa (job #2806584) | Cod sursa (job #72338) | Cod sursa (job #2642948)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
ifstream in ("maxflow.in");
ofstream out("maxflow.out");
struct Dinic{
const int oo=2e9;
struct mc{
int u, v, capacity, flow=0;
mc(int uu, int vv, int capp){
u=uu; v=vv; capacity=capp;
}
};
int s, t;
queue <int> q;
vector <mc> muchii;
vector <vector<int> > vecini;
vector <int> lastPtr, bfsLevel;
Dinic(int n, int ss, int tt){
lastPtr.resize(n+1);
vecini.resize(n+1);
bfsLevel.resize(n+1);
s=ss; t=tt;
}
void insert_edge(int x, int y, int cap){
muchii.push_back(mc{x, y, cap});
vecini[x].push_back(muchii.size()-1);
muchii.push_back(mc{y, x, 0});
vecini[y].push_back(muchii.size()-1);
}
int dfsFlow(int nodAct, int fluxAct){
if(fluxAct==0)
return 0;
if(nodAct==t)
return fluxAct;
for(int & att=lastPtr[nodAct]; att<(int)vecini[nodAct].size(); att++){///mut efectiv pointer-ul respectiv
int id=vecini[nodAct][att];
int nodNext=muchii[id].v;
if(bfsLevel[nodNext]!=bfsLevel[nodAct]+1) ///flux path-ul nu are lungimea cea mai mica de la bfs
continue;
if(muchii[id].capacity-muchii[id].flow<1) ///adica e saturata muchia
continue;
int tempFlow=dfsFlow(nodNext, min(fluxAct, muchii[id].capacity-muchii[id].flow));
if(tempFlow==0) ///pe muchia asta n-am sanse
continue;
muchii[id].flow+=tempFlow;
muchii[id^1].flow-=tempFlow;
return tempFlow;
///se presupune ca muchiile consecutive in graful rezidual se inverseaza reciproc
}
return 0; ///in caz ca toate muchiile nu merg
}
bool bfsFlow(){
fill(bfsLevel.begin(), bfsLevel.end(), -1);
bfsLevel[s]=0;
q.push(s);
while(!q.empty()){
int nodAct = q.front();
q.pop();
for(int id:vecini[nodAct]){
if(muchii[id].capacity-muchii[id].flow<1)
continue;
if(bfsLevel[muchii[id].v]!=-1)
continue;
bfsLevel[muchii[id].v]=bfsLevel[nodAct]+1;
q.push(muchii[id].v);
}
}
return bfsLevel[t]!=-1;
}
long long maxFlow(){ ///sursa si scurgere
long long ans=0;
while(true){
if(!bfsFlow())
break;
fill(lastPtr.begin(), lastPtr.end(), 0); ///ca la fiecare dfs sa am toate muchiile disponibile de la inceput (exceptie cele saturate)
while(int moreFlow=dfsFlow(s, oo) ){
ans+=moreFlow;
}
}
return ans;
}
};
int n, m;
int x, y, c;
int main()
{
in>>n>>m;
Dinic dc(n, 1, n);
for(int i=1; i<=m; i++){
in>>x>>y>>c;
dc.insert_edge(x, y, c);
}
out<<dc.maxFlow();
return 0;
}