zoukankan      html  css  js  c++  java
  • Marriage Match IV HDU

    题面

    点击跳转

    题解

    以为是价值流, 把 dis[t] 卡着最小值就好了, t飞了

    那只能删边, 跑最大流了, 只保留最短路径上的边就好了

    s, t正反跑, 把不是最短路上的边直接删了(ne[i] = ne[ne[i]])

    代码

    #include <bits/stdc++.h>
    #define all(n) (n).begin(), (n).end()
    #define se second
    #define fi first
    #define pb push_back
    #define mp make_pair
    #define sqr(n) (n)*(n)
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i=(a);i>=(b);--i)
    #define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PII;
    typedef pair<ll, ll> PLL;
    typedef vector<int> VI;
    
    const int N = 1e3 + 5, M = 2e5 + 5, inf = 1 << 30;
    
    int n, m, _, k;
    int h[N], to[M], ne[M], co[M], tot;
    int v[N], incf[N], pre[N], maxflow, d[N], ans, s, t;
    int da[N], db[N];
    
    void add(int u, int v, int c) {
        ne[++tot] = h[u]; to[h[u] = tot] = v; co[tot] = c;
        ne[++tot] = h[v]; to[h[v] = tot] = u; co[tot] = -c;
    }
    
    bool bfs() {
        rep (i, 1, n) d[i] = 0;
        queue<int> q; q.push(s); d[s] = 1;
        while (!q.empty()) {
            int x = q.front(); q.pop();
            for (int i = h[x]; i; i = ne[i]) {
                if (!co[i]) continue;
                int y = to[i];
                if (d[y]) continue;
                d[y] = d[x] + 1; q.push(y);
                if (y == t) return 1;
            }
        }
        return 0;
    }
    
    int dinic(int x, int flow) {
        if (x == t) return flow;
        int rest = flow, k;
        for (int i = h[x]; i && rest; i = ne[i]) {
            if (!co[i]) continue;
            int y = to[i];
            if (d[y] != d[x] + 1) continue;
            k = dinic(y, min(rest, co[i]));
            if (!k) d[y] = 0;
            co[i] -= k, co[i ^ 1] += k; rest -= k;
        }
        return flow - rest;
    }
    
    void dij(int d[], int s, bool f) {
        rep(i, 1, n) d[i] = inf, v[i] = 0; d[s] = 0;
        priority_queue<PII> q; q.push({ 0, s });
        while (!q.empty()) {
            int x = q.top().se; q.pop();
            if (v[x]) continue; v[x] = 1;
            for (int i = h[x]; i; i = ne[i]) {
                if ((i & 1) != f) continue;
                int w = d[x] + abs(co[i]), y = to[i];
                if (w >= d[y]) continue;
                d[y] = w; q.push({ -d[y], y });
            }
        }
    }
    
    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n >> m;
            rep(i, 1, n) h[i] = 0;
            tot = 1; maxflow = ans = 0;
            rep(i, 1, m) {
                int u, v, c; cin >> u >> v >> c;
                add(u, v, c);
            }
            cin >> s >> t; dij(da, s, 0); dij(db, t, 1);
            rep (k, 1, n)
                for (int i = h[k], *j = &h[k]; i; i = ne[i])
                    if (i & 1)
                        if (db[k] - co[i] + da[to[i]] != db[s]) *j = ne[i];
                        else j = &ne[i], co[i] = 0;
                    else
                        if (da[k] + co[i] + db[to[i]] != da[t]) *j = ne[i];
                        else j = &ne[i], co[i] = 1;
            int flow = 0;
            while (bfs()) while (flow = dinic(s, inf)) maxflow += flow;
            cout << maxflow << '
    ';
        }
        return 0;
    }
    
  • 相关阅读:
    FreeBie—免费设计师专用素材网
    8个高质量免抠素材网站
    微信公众号开发之刷卡支付
    微信公众号开发之扫码支付
    HEXO+PAGE 搭建个性博客
    微信扫码支付(模式一)
    常用的开源框架
    Java实现Excel导入数据库,数据库中的数据导入到Excel
    微信公众平台开发教程第5篇-----网页授权获取用户基本信息
    t-io 集群解决方案以及源码解析
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13827820.html
Copyright © 2011-2022 走看看