1. 程式人生 > >luogu1345 奶牛的電信

luogu1345 奶牛的電信

highlight print ring tro dde 模板題 algo ret 不可

  拆點、最小割的模板題。

  我只想說一點。拆點時不可以下意識地初始化!起點和終點不能直接寫編號!寫拆點後的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\n", g.MaxFlow());
    return 0;
}

  

luogu1345 奶牛的電信