• luogu1345 奶牛的电信


      拆点、最小割的模板题。

      我只想说一点。拆点时不可以下意识地初始化!起点和终点不能直接写编号!写拆点后的Id!

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    
    #define In(x) (x) * 2 - 1
    #define Out(x) (x) * 2
    const int MAX_NODE = 210, MAX_EDGE = 210 * 210 * 2, INF = 0x3f3f3f3f;
    
    struct Dinic
    {
    private:
        struct Node;
        struct Edge;
    
        struct Node
        {
            Edge *Head, *DfsFrom;
            int Level;
        }_nodes[MAX_NODE], *Start, *Target;
        int TotNode;
    
        struct Edge
        {
            Node *To;
            Edge *Next, *Rev;
            int Cap;
        }_edges[MAX_EDGE];
        int _eCount;
    
        Edge *AddEdge(Node *from, Node *to, int cap)
        {
            Edge *e = _edges + ++_eCount;
            e->To = to;
            e->Cap = cap;
            e->Next = from->Head;
            from->Head = e;
            return e;
        }
    
        bool Bfs()
        {
            for (int i = 1; i <= TotNode; i++)
                _nodes[i].Level = 0;
            Start->Level = 1;
            static queue<Node*> q;
            q.push(Start);
            while (!q.empty())
            {
                Node *cur = q.front();
                q.pop();
                for (Edge *e = cur->Head; e; e = e->Next)
                {
                    if (e->Cap && !e->To->Level)
                    {
                        e->To->Level = cur->Level + 1;
                        q.push(e->To);
                    }
                }
            }
            return Target->Level;
        }
    
        int Dfs(Node *cur, int limit)
        {
            if (cur == Target)
                return limit;
            if (limit == 0)
                return 0;
            int curTake = 0;
            for (Edge *e = cur->DfsFrom; e; e = (cur->DfsFrom) = e->Next)
            {
                if (e->Cap && e->To->Level == cur->Level + 1)
                {
                    int nextTake = Dfs(e->To, min(limit - curTake, e->Cap));
                    curTake += nextTake;
                    e->Cap -= nextTake;
                    e->Rev->Cap += nextTake;
                }
                if (curTake == limit)
                    break;
            }
            return curTake;
        }
    
    public:
        void Init(int n, int s, int t)
        {
            TotNode = n;
            Start = _nodes + s;
            Target = _nodes + t;
        }
    
        void Build(int uId, int vId, int cap)
        {
            Node *u = _nodes + uId, *v = _nodes + vId;
            Edge *e1 = AddEdge(u, v, cap), *e2 = AddEdge(v, u, 0);
            e1->Rev = e2;
            e2->Rev = e1;
        }
    
        int MaxFlow()
        {
            int ans = 0;
            while (Bfs())
            {
                for (int i = 1; i <= TotNode; i++)
                    _nodes[i].DfsFrom = _nodes[i].Head;
                ans += Dfs(Start, INF);
            }
            return ans;
        }
    }g;
    
    int main()
    {
        int totNode, totEdge, s, t;
        scanf("%d%d%d%d", &totNode, &totEdge, &s, &t);
        g.Init(totNode * 2, Out(s), In(t));//!!!!!!!!!!!!!!!!!!!!!!!!!!
        for (int i = 1; i <= totNode; i++)
            g.Build(In(i), Out(i), 1);
        for (int i = 1; i <= totEdge; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            g.Build(Out(u), In(v), INF);
            g.Build(Out(v), In(u), INF);
        }
        printf("%d
    ", g.MaxFlow());
        return 0;
    }
    

      

  • 相关阅读:
    长为N的数组,元素范围是0-N-1,其中只有一个数是重复的,找出这个重复元素
    KMP算法
    最长公共子序列,最长公共字串,最长递增子序列
    马走日字问题
    URL详解
    分辨率、像素和PPI
    输入一棵二叉树,判断该二叉树是否是平衡二叉树。
    返回值递归问题
    图像几何变换:旋转,缩放,错切
    数据库事务的四大特性以及事务的隔离级别
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9484177.html
Copyright © 2020-2023  润新知