最大フロー
add(u,v,f) u ~ v にcapがfの辺を追加して
flow(s,t) で結果が出てくる
class din{
struct edge{
int to;
int cap;
int rev;
};
public :
int n;
vector<vector<edge>> g;
vector<int> level;
vector<int> ite;
din(int x){
n = x;
g.resize(n);
level.resize(n);
ite.resize(n);
}
void add(int from,int to,int cap){
g[from].push_back(edge{to,cap,(int)g[to].size()});
g[to].push_back(edge{from,0,(int)g[from].size()-1});
}
bool bfs(int s,int t){
level.assign(n,-1);
queue<int> q;
q.push(s);
level[s] = 0;
while(q.size()!=0){
int pos = q.front();
q.pop();
for(const edge& e : g[pos]){
if(e.cap > 0 && level[e.to] < 0){
level[e.to] = level[pos]+1;
q.push(e.to);
}
}
}
return level[t] >= 0;
}
int dfs(int v,int t,int f){
if(v==t)return f;
for(int &i = ite[v];i < (int)g[v].size();i++){
edge& e = g[v][i];
if(e.cap > 0 && level[v] < level[e.to]){
int d = dfs(e.to,t,min(f,e.cap));
if(d > 0){
e.cap -= d;
g[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int flow(int s,int t){
int ans = 0;
while(1){
if(!bfs(s,t))break;
ite.assign(n,0);
int f = dfs(s,t,INF);
while(1){
if(f>0){
ans += f;
f = dfs(s,t,INF);
}
else{
break;
}
}
}
return ans;
}
};
辺を復元したい
class din{
struct edge{
int to;
int cap;
int rev;
};
public :
int n;
vector<vector<edge>> g;
vector<int> level;
vector<int> ite;
din(int x){
n = x;
g.resize(n);
level.resize(n);
ite.resize(n);
}
void add(int from,int to,int cap){
g[from].push_back(edge{to,cap,(int)g[to].size()});
g[to].push_back(edge{from,0,(int)g[from].size()-1});
}
bool bfs(int s,int t){
level.assign(n,-1);
queue<int> q;
q.push(s);
level[s] = 0;
while(q.size()!=0){
int pos = q.front();
q.pop();
for(const edge& e : g[pos]){
if(e.cap > 0 && level[e.to] < 0){
level[e.to] = level[pos]+1;
q.push(e.to);
}
}
}
return level[t] >= 0;
}
int dfs(int v,int t,int f){
if(v==t)return f;
for(int &i = ite[v];i < (int)g[v].size();i++){
edge& e = g[v][i];
if(e.cap > 0 && level[v] < level[e.to]){
int d = dfs(e.to,t,min(f,e.cap));
if(d > 0){
e.cap -= d;
g[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int flow(int s,int t,vector<pair<int,int>>& res){
int ans = 0;
while(1){
if(!bfs(s,t))break;
ite.assign(n,0);
int f = dfs(s,t,INF);
while(1){
if(f>0){
ans += f;
f = dfs(s,t,INF);
}
else{
break;
}
}
}
rep(i,n){
for(edge& e : g[i]){
if(e.to==s || e.to==t)continue;
if(e.cap==0){
res.push_back({i,e.to});
}
}
}
return ans;
}
int flow(int s,int t){
int ans = 0;
while(1){
if(!bfs(s,t))break;
ite.assign(n,0);
int f = dfs(s,t,INF);
while(1){
if(f>0){
ans += f;
f = dfs(s,t,INF);
}
else{
break;
}
}
}
return ans;
}
};