zoukankan      html  css  js  c++  java
  • [CF546E] Soldier and Traveling

    [CF546E] Soldier and Traveling - 最大流

    Description

    (n le 100) 个城市,(m le 200) 条边。然后人只能从走相邻边相连的城市。现在给你初始城市的每一个人数,再给一组每个城市人数。询问是否可以从当前人数变换到给定人数。

    Solution

    直接对城市拆点为入点、出点后跑最大流

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    #ifndef __FLOW_HPP__
    #define __FLOW_HPP__
    
    // v1.1     feat. edge query for Maxf
    
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    
    namespace flowsolution
    {
        const int N = 100005;
        const int M = 1000005;
        const int inf = 1e+12;
    
        struct MaxflowSolution
        {
            int *dis, ans, cnt = 1, s, t, *pre, *next, *head, *val;
    
            MaxflowSolution()
            {
                cnt = 1;
                dis = new int[N];
                pre = new int[M];
                next = new int[M];
                head = new int[N];
                val = new int[M];
                fill(dis, dis + N, 0);
                fill(pre, pre + M, 0);
                fill(next, next + M, 0);
                fill(head, head + N, 0);
                fill(val, val + M, 0);
            }
    
            ~MaxflowSolution()
            {
                delete[] dis;
                delete[] pre;
                delete[] next;
                delete[] head;
                delete[] val;
            }
    
            std::queue<int> q;
            int make(int x, int y, int z)
            {
                pre[++cnt] = y, next[cnt] = head[x], head[x] = cnt, val[cnt] = z;
                int ret = cnt;
                pre[++cnt] = x, next[cnt] = head[y], head[y] = cnt;
                return ret;
            }
    
            int get_value(int x)
            {
                return val[x];
            }
    
            bool bfs()
            {
                fill(dis, dis + N, 0);
                q.push(s), dis[s] = 1;
                while (!q.empty())
                {
                    int x = q.front();
                    q.pop();
                    for (int i = head[x]; i; i = next[i])
                        if (!dis[pre[i]] && val[i])
                            dis[pre[i]] = dis[x] + 1, q.push(pre[i]);
                }
                return dis[t];
            }
    
            int dfs(int x, int flow)
            {
                if (x == t || !flow)
                    return flow;
                int f = flow;
                for (int i = head[x]; i; i = next[i])
                    if (val[i] && dis[pre[i]] > dis[x])
                    {
                        int y = dfs(pre[i], min(val[i], f));
                        f -= y, val[i] -= y, val[i ^ 1] += y;
                        if (!f)
                            return flow;
                    }
                if (f == flow)
                    dis[x] = -1;
                return flow - f;
            }
    
            int solve(int _s, int _t)
            {
                s = _s;
                t = _t;
                ans = 0;
                for (; bfs(); ans += dfs(s, inf))
                    ;
                return ans;
            }
        };
    
        struct CostflowSolution
        {
            struct Edge
            {
                int p = 0, c = 0, w = 0, next = -1;
            } * e;
            int s, t, tans, ans, cost, ind, *bus, qhead = 0, qtail = -1, *qu, *vis, *dist;
    
            CostflowSolution()
            {
                e = new Edge[M];
                qu = new int[M];
                bus = new int[N];
                vis = new int[N];
                dist = new int[N];
                fill(qu, qu + M, 0);
                fill(bus, bus + N, -1);
                fill(vis, vis + N, 0);
                fill(dist, dist + N, 0);
                ind = 0;
            }
    
            ~CostflowSolution()
            {
                delete[] e;
                delete[] qu;
                delete[] vis;
                delete[] dist;
            }
    
            void graph_link(int p, int q, int c, int w)
            {
                e[ind].p = q;
                e[ind].c = c;
                e[ind].w = w;
                e[ind].next = bus[p];
                bus[p] = ind;
                ++ind;
            }
    
            void make(int p, int q, int c, int w)
            {
                graph_link(p, q, c, w);
                graph_link(q, p, 0, -w);
            }
    
            int dinic_spfa()
            {
                qhead = 0;
                qtail = -1;
                fill(vis, vis + N, 0);
                fill(dist, dist + N, inf);
                vis[s] = 1;
                dist[s] = 0;
                qu[++qtail] = s;
                while (qtail >= qhead)
                {
                    int p = qu[qhead++];
                    vis[p] = 0;
                    for (int i = bus[p]; i != -1; i = e[i].next)
                        if (dist[e[i].p] > dist[p] + e[i].w && e[i].c > 0)
                        {
                            dist[e[i].p] = dist[p] + e[i].w;
                            if (vis[e[i].p] == 0)
                                vis[e[i].p] = 1, qu[++qtail] = e[i].p;
                        }
                }
                return dist[t] < inf;
            }
    
            int dinic_dfs(int p, int lim)
            {
                if (p == t)
                    return lim;
                vis[p] = 1;
                int ret = 0;
                for (int i = bus[p]; i != -1; i = e[i].next)
                {
                    int q = e[i].p;
                    if (e[i].c > 0 && dist[q] == dist[p] + e[i].w && vis[q] == 0)
                    {
                        int res = dinic_dfs(q, min(lim, e[i].c));
                        cost += res * e[i].w;
                        e[i].c -= res;
                        e[i ^ 1].c += res;
                        ret += res;
                        lim -= res;
                        if (lim == 0)
                            break;
                    }
                }
                return ret;
            }
    
            pair<int, int> solve(int _s, int _t)
            {
                s = _s;
                t = _t;
                ans = 0;
                cost = 0;
                while (dinic_spfa())
                {
                    fill(vis, vis + N, 0);
                    ans += dinic_dfs(s, inf);
                }
                return make_pair(ans, cost);
            }
        };
    } // namespace flowsolution
    
    #endif
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int n, m;
        cin >> n >> m;
    
        int NODE_IN = 0;
        int NODE_OUT = n;
        int S = 2 * n + 1;
        int T = 2 * n + 2;
        int target = 0;
        int target_s = 0;
        flowsolution::MaxflowSolution flow;
    
        map<int, int> mp_stay;
    
        for (int i = 1; i <= n; i++)
        {
            int in_flow;
            cin >> in_flow;
            target_s += in_flow;
            flow.make(S, NODE_IN + i, in_flow);
        }
        for (int i = 1; i <= n; i++)
        {
            int out_flow;
            cin >> out_flow;
            mp_stay[i] = flow.make(NODE_IN + i, NODE_OUT + i, 1e12);
            flow.make(NODE_OUT + i, T, out_flow);
            target += out_flow;
        }
    
        map<pair<int, int>, int> mp;
    
        for (int i = 1; i <= m; i++)
        {
            int u, v;
            cin >> u >> v;
            mp[{u, v}] = flow.make(NODE_IN + u, NODE_OUT + v, 1e12);
            mp[{v, u}] = flow.make(NODE_IN + v, NODE_OUT + u, 1e12);
        }
    
        int ans = flow.solve(S, T);
        if (target == ans && target_s == ans)
        {
            cout << "YES" << endl;
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= n; j++)
                {
                    if (i == j)
                        cout << flow.get_value(mp_stay[i] ^ 1) << " ";
                    else if (mp[{i, j}])
                        cout << flow.get_value(mp[{i, j}] ^ 1) << " ";
                    else
                        cout << "0 ";
                }
                cout << endl;
            }
        }
        else
        {
            cout << "NO" << endl;
        }
    }
    
  • 相关阅读:
    【Java EE 学习 36】【struts2】【struts2系统验证】【struts2 ognl值栈】【struts2 ongl标签】【struts2 UI标签】【struts2模型驱动和令牌机制】
    【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】
    【Java EE 学习 35 上】【strus2】【类型转换器】【struts2和Servlet API解耦】【国际化问题】【资源文件乱码问题已经解决】
    【Java EE 学习 34】【struts2学习第一天】
    【JavaScript中的正则表达式】
    【Java EE 学习 33 下】【validate表单验证插件】
    【Java EE 学习 33 上】【JQuery样式操作】【JQuery中的Ajax操作】【JQuery中的XML操作】
    【Java EE 学习 32 下】【JQuery】【JQuey中的DOM操作】
    【Java EE 学习 32 上】【JQuery】【选择器】
    【Java EE 学习 31】【JavaScript基础增强】【Ajax基础】【Json基础】
  • 原文地址:https://www.cnblogs.com/mollnn/p/14355883.html
Copyright © 2011-2022 走看看