Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct Dinic{
- struct Edge{
- int u, v;
- ll cap, flow = 0;
- Edge(int u, int v, ll cap) : u(u), v(v), cap(cap) {}
- };
- const ll flow_inf = 1e18;
- vector<Edge> edges;
- vector<vector<int>> adj;
- int n, m = 0;
- int s, t;
- vector<int> level, ptr;
- queue<int> q;
- Dinic(int n, int s, int t) : n(n), s(s), t(t){
- adj = vector<vector<int>>(n);
- level = vector<int>(n);
- ptr = vector<int>(n);
- }
- void add_edge(int u, int v, ll cap){
- edges.emplace_back(u, v, cap);
- edges.emplace_back(v, u, 0);
- adj[u].push_back(m);
- adj[v].push_back(m+1);
- m += 2;
- }
- bool bfs(){
- while(!q.empty()){
- int v = q.front();
- q.pop();
- for(int id : adj[v]){
- if(edges[id].cap == edges[id].flow) continue;
- if(level[edges[id].v] != -1) continue;
- level[edges[id].v] = level[v] + 1;
- q.push(edges[id].v);
- }
- }
- return level[t] != -1;
- }
- ll dfs(int v, ll pushed){
- if(!pushed) return 0;
- if(v == t) return pushed;
- for(int& cid = ptr[v]; cid < (int)adj[v].size(); cid++){
- int id = adj[v][cid];
- int u = edges[id].v;
- if(level[v] + 1 != level[u] || edges[id].cap == edges[id].flow) continue;
- ll tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow));
- if(tr == 0) continue;
- edges[id].flow += tr;
- edges[id^1].flow -= tr;
- return tr;
- }
- return 0;
- }
- ll flow(){
- ll f = 0;
- while(true){
- fill(level.begin(), level.end(), -1);
- level[s] = 0;
- q.push(s);
- if(!bfs()) break;
- fill(ptr.begin(), ptr.end(), 0);
- while(ll pushed = dfs(s, flow_inf)){
- f += pushed;
- }
- }
- return f;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement