图论-最大流Dinic

点击查看代码
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int N = 500;
const int M = 10010;
const int mod = 1e9 + 7;

int n, m, s, t;

int head[N], cnt = 1;
struct Edge{
    int from, to, nxt;
    ll val;
}e[M];
void add(int u, int v, ll w){
    e[++cnt].from = u;
    e[cnt].to = v;
    e[cnt].nxt = head[u];
    e[cnt].val = w;
    head[u] = cnt;
}

int now[N], dep[N]; // dep 记录点所在的层次
int bfs(){
    for(int i = 1; i <= n; i++) dep[i] = 1e9;
    dep[s] = 0;
    now[s] = head[s];
    queue<int> Q; Q.push(s);
    while(!Q.empty()){
        int u = Q.front(); Q.pop();
        for(int i = head[u]; i != 0; i = e[i].nxt){ // 搜索点 u 的所有邻居,邻居是下一层
            int v = e[i].to;
            if(e[i].val > 0 && dep[v] == 1e9){
                Q.push(v);
                now[v] = head[v];
                dep[v] = dep[u] + 1;
                if(v == t) return 1;
            }
        }
    }
    return 0;
}

ll dfs(int u, ll sum){
    if(u == t) return sum;
    ll k, flow = 0;
    for(int i = now[u]; i > 0 && sum > 0; i = e[i].nxt){
        now[u] = i; // 当前弧优化
        int v = e[i].to;
        if(e[i].val > 0 && (dep[v] == dep[u] + 1)){
            k = dfs(v, min(sum, e[i].val));
            if(k == 0) dep[v] = 1e9;
            e[i].val -= k;
            e[i^1].val += k;
            flow += k;
            sum -= k;
        }
    }
    return flow;
}

void solve() {
    cin >> n >> m >> s >> t;
    for(int i = 1; i <= m; i++){
        int u, v;
        ll w;
        cin >> u >> v >> w;
        add(u, v, w);
        add(v, u, 0);
    }

    ll ans = 0;
    while(bfs()){
        ans += dfs(s, inf);
    }
    cout << ans << endl;
}
posted @ 2024-05-24 13:46  9102700  阅读(15)  评论(0)    收藏  举报