其他分享
首页 > 其他分享> > P4843 清理雪道

P4843 清理雪道

作者:互联网

上下界网络流最小流

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#define FT(a, b) memset(a, b, sizeof(a))
#define FAT(a) memset(a, 0, sizeof(a))
using namespace std;

const int N = 50003 + 10, M = (125003+ N) * 2;
const int INF = 0x3f3f3f3f;
int n, m, s, t, S, T;
int h[N], ne[M], e[M], idx, w[M];
int deepth[N], cur[N], all[N], gap[N];
void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
    swap(a, b), c = 0;
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
void bfs()
{
    FT(deepth, -1);
    FAT(gap);
    queue<int> q;
    q.push(t);
    deepth[t] = 0;
    gap[0] = 1;
    while (q.size())
    {
        int a = q.front();
        q.pop();
        for (int i = h[a]; ~i; i = ne[i])
        {
            int j = e[i];
            if (deepth[j] == -1)
            {
                deepth[j] = deepth[a] + 1;
                gap[deepth[j]]++;
                q.push(j);
            }
        }
    }
}
// int ans;
int dfs(int now, int flow)
{
    if (now == t)
    {
        // ans += flow;
        return flow;
    }
    int nowflow = 0;
    for (int i = cur[now]; ~i; i = ne[i])
    {
        cur[now] = i;
        int j = e[i];
        if (w[i] && deepth[j] + 1 == deepth[now])
        {
            int k = dfs(j, min(flow - nowflow, w[i]));
            w[i] -= k, w[i ^ 1] += k, nowflow += k;
            if (nowflow == flow)
                return nowflow;
        }
    }
    --gap[deepth[now]];
    if (!gap[deepth[now]])
        gap[s] = n + 2;
    ++deepth[now];
    ++gap[deepth[now]];
    return nowflow;
}

int ISAP()
{
    int ans = 0;
    bfs();
    while (gap[s] < n)
    {
        memcpy(cur, h, sizeof(cur));
        ans += dfs(s, INF);
    }
    return ans;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("/home/wjy/code/in.txt", "r", stdin);
    // freopen("/home/wjy/code/ans1.txt","w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    FT(h, -1), idx = 0;
    FAT(all);
    cin >> n;
    S = 0, T = ++n;
    s = n + 1, t = n + 2;
    for (int i = 1; i <= n; i++)
    {
        cin >> m;
        add(S, i, INF), add(i, T, INF);
        while (m > 0)
        {
            m--;
            int x;
            cin >> x;
            add(i, x, INF - 1);
            all[i] -= 1, all[x] += 1;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        // cout << i << " " << all[i] << endl;
        if (all[i] > 0)
            add(s, i, all[i]);
        else
            add(i, t, -all[i]);
    }
    // ISAP();
    add(T, S, INF);
    // cout << ISAP() << endl;
    ISAP();
    int flow = w[idx - 1];
    // cout << flow << endl;
    w[idx - 1] = w[idx - 2] = 0;
    s = T, t = S;
    cout << flow - ISAP() << endl;
    return 0;
}

 

标签:now,idx,int,清理,P4843,雪道,deepth,add,gap
来源: https://www.cnblogs.com/ignorance/p/14091457.html