zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    Java基础知识_毕向东_Java基础视频教程笔记(5-10 面向对象)
    Java 运算符-=,+=混合计算详解
    VS Code 基本介绍 和 快捷键
    Access-Control-Allow-Origin 跨域问题
    Linux常用命令收藏
    常用正则表达式
    IntelliJ IDEA 快捷键列表
    PAT A除以B
    PAT 部分A+B
    PAT 德才论
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9484177.html
Copyright © 2011-2022 走看看