图论模版

链式前向星

namespace Graph_nxt
{
    const int maxn = 1e5, maxm = 1e5;
    struct Edge
    {
        int v, f;
        friend bool operator <(Edge a, Edge b)
        {
            return a.f > b.f;
        }
    };
    Edge edg[maxm];
    int  h[maxn], nxt[maxm];
    int esize;
    inline void add(int u, int v, int w)
    {
        esize++;
        edg[esize] = { v,w };
        nxt[esize] = h[u];
        h[u] = esize;
    }
}

连通性

并查集

const int maxn = 1000;
struct Unionset
{
	int f[maxn];
	Unionset(int n)
	{
		for (int i = 0; i <= n; i++)
		{
			f[i] = i;
		}
	}
	int find(int x)
	{
		return x == f[x] ? x : f[x] = find(f[x]);
	}
	bool query(int x, int y)
	{
		return find(x) ==find(y);
	}
	void uni(int x, int y)
	{
		f[find(x)] = find(y);
	}
};

tarjan

namespace Tarjan
{
    const int maxn=1000, maxm=1000;
    struct Graph
    {
        Graph()
        {
            esize = 0;
            memset(h,0,sizeof(h));
            memset(nxt, 0, sizeof(nxt));
        }
        int edg[maxm];
        int  h[maxn], nxt[maxm];
        int esize;
        inline void add(int u, int v)
        {
            esize++;
            edg[esize] = v;
            nxt[esize] = h[u];
            h[u] = esize;
        }
    };
    Graph g1, g2;
    int dfn[maxn], low[maxn], num = 0, scc[maxn], sccn = 0, sk[maxn], sksize = 0, sum[maxn], mxsum = 0;
    void tarjan(int u)
    {
        dfn[u] = low[u] = ++num;
        sk[sksize++] = u;
        for (int i = g1.h[u]; i; i = g1.nxt[i])
        {
            int v = g1.edg[i];
            if (!dfn[v])
            {
                tarjan(v);
                low[u] = mn(low[u], low[v]);
            }
            else if (!scc[v])
            {
                low[u] = mn(low[u], dfn[v]);
            }
        }
        if (dfn[u] == low[u])
        {
            sccn++;
            while (1)
            {
                int v = sk[--sksize];
                scc[v] = sccn;
                if (v == u)break;
            }
        }
    }
}

最短路

dijkstra

namespace Dijkstra
{
    const int maxn = 100005, maxm = 200005;
    struct Edge
    {
        int v, w;
        bool operator <(const Edge& x)const
        {
            return w > x.w;
        }
    };
    int e;
    struct Graph
    {
        void ini(int _n)
        {
            n = _n;
            esize = 0;
            memset(nxt, 0, sizeof(nxt));
            memset(h, 0, sizeof(h));
        }
        Edge edg[maxm];
        int  h[maxn], nxt[maxm], esize, n;
        inline void add(int u, int v, int w)
        {
            esize++;
            edg[esize] = { v,w };
            nxt[esize] = h[u];
            h[u] = esize;
        }
        int dis[maxn], vis[maxn];
        void dijkstra(int s)
        {
            priority_queue<Edge> q;
            memset(dis, 127, sizeof(dis));
            memset(vis, 0, sizeof(vis));
            dis[s] = 0;
            q.push({ s,0 });
            while (!q.empty())
            {
                int u = q.top().v, w = q.top().w;
                q.pop();
                if (w != dis[u])continue;
                vis[u] = 1;
                for (int i = h[u]; i; i = nxt[i])
                {
                    int v = edg[i].v;
                    if (!vis[v] && dis[v] > w + edg[i].w)
                    {
                        dis[v] = w + edg[i].w;
                        q.push({ v,dis[v] });
                    }
                }
            }
        }
    }g;
}

网络流

dinic

namespace DINIC
{
    const int maxn = 205, maxm = 5005 * 2, inf = 0x3f3f3f3f;
    struct Edge
    {
        int v, w;
    };
    int e;
    struct Graph
    {
        void ini(int _n)
        {
            n = _n;
            esize = 1;
            memset(nxt, 0, sizeof(nxt));
            memset(h, 0, sizeof(h));
        }
        Edge edg[maxm];
        int  h[maxn], nxt[maxm], esize, n;
        inline void add(int u, int v, int w)
        {
            esize++;
            edg[esize] = { v,w };
            nxt[esize] = h[u];
            h[u] = esize;
        }
        int dep[maxn], inq[maxn], cur[maxn];
        int s, t;
        long long mxflow;
        bool tag;
        bool bfs()
        {
            for (int i = 1; i <= n; i++)
            {
                cur[i] = h[i];
                dep[i] = inf;
                inq[i] = 0;
            }
            queue<int> q;
            q.push(s);
            dep[s] = 0;
            inq[s] = 1;
            while (!q.empty())
            {
                int u = q.front();
                q.pop();
                for (int i = h[u]; i; i = nxt[i])
                {
                    int v = edg[i].v;
                    if (edg[i].w > 0 && dep[u] + 1 < dep[v])
                    {
                        dep[v] = dep[u] + 1;
                        if (!inq[v])
                        {
                            q.push(v);
                            inq[v] = 1;
                        }
                    }
                }
            }
            if (dep[t] == inf)return 0;
            return 1;
        }
        inline long long dfs(int u, long long mnflow)
        {
            long long usflow = 0, tmpflow = 0;
            if (u == t)
            {
                return mnflow;
            }
            for (int i = cur[u]; i; i = nxt[i])
            {
                cur[u] = i;
                int v = edg[i].v;
                if (edg[i].w > 0 && dep[v] == dep[u] + 1)
                {
                    tmpflow = dfs(v, mn(mnflow, edg[i].w));
                    if (!tmpflow) dep[v] = inf;
                    edg[i].w -= tmpflow;
                    edg[i ^ 1].w += tmpflow;
                    usflow += tmpflow;
                    mnflow -= tmpflow;
                    if (!mnflow)break;
                }
            }
            return usflow;
        }
        long long dinic(int _s, int _e)
        {
            s = _s;
            t = _e;
            mxflow = 0;
            while (bfs())
            {
                tag = 1;
                while (tag)
                {
                    tag = 0;
                    mxflow += dfs(s, INT_MAX);
                }
            }
            return mxflow;
        }
    }g;
}

ISAP

namespace ISAP
{
    const int maxn = 1e5, maxm = 1e5;
    struct Edge
    {
        int v, w;
    };
    struct Graph
    {
        int h[maxn], nxt[maxm], esize, n;
        Edge edg[maxm];
        void ini(int _n)
        {
            n = _n;
            memset(h, 0, sizeof(h));
            memset(nxt, 0, sizeof(nxt));
            esize = 1;
        }
        void inline add(int u, int v, int w)
        {
            esize++;
            edg[esize] = { v,w };
            nxt[esize] = h[u];
            h[u] = esize;
        }
        int cur[maxn], gap[maxn], bfn[maxn], s, t;
        void bfs()
        {
            queue<int> q;
            memset(bfn, 0, sizeof(bfn));
            memset(gap, 0, sizeof(gap));
            for (int i = 1; i <= n; i++)
            {
                cur[i] = h[i];
            }
            q.push(t);
            bfn[t] = 1;
            gap[1]++;
            while (!q.empty())
            {
                int u = q.front();
                q.pop();
                for (int i = h[u]; i; i = nxt[i])
                {
                    int v = edg[i].v;
                    if (bfn[v])continue;
                    bfn[v] = bfn[u] + 1;
                    gap[bfn[v]]++;
                    q.push(v);
                }
            }
        }
        long long dfs(int u, int minflow)
        {
            if (u == t)return minflow;
            int useflow = 0;
            for (int& i = cur[u]; i; i = nxt[i])
            {
                int v = edg[i].v;
                if (bfn[v] + 1 != bfn[u] || edg[i].w <= 0)continue;
                long long tmp = dfs(v, min(minflow, edg[i].w));
                if (tmp)
                {
                    useflow += tmp;
                    minflow -= tmp;
                    edg[i].w -= tmp;
                    edg[i ^ 1].w += tmp;
                    if (!minflow)return useflow;
                }
            }
            gap[bfn[u]]--;
            if (!gap[bfn[u]])bfn[s] = n + 1;
            bfn[u]++;
            gap[bfn[u]]++;
            cur[u] = h[u];
            return useflow;
        }
        long long isap(int _s, int _t)
        {
            s = _s;
            t = _t;
            bfs();
            long long maxflow = 0;
            while (bfn[s] <= n)
            {
                maxflow += dfs(s, INT_MAX);
            }
            return maxflow;
        }
    }g;
}

最小费用最大流

namespace MCMF
{
    const int maxn = 5005, maxm = 50005 * 2, inf = 0x3f3f3f3f;
    struct Edge
    {
        int v, w, f;
    };
    struct Graph
    { 
        void ini(int _n)
        {
            n = _n;
            esize = 1;
            memset(nxt, 0, sizeof(nxt));
            memset(h, 0, sizeof(h));
        }
        Edge edg[maxm];
        int  h[maxn], nxt[maxm], esize, n;
        inline void add(int u, int v, int w, int f)
        {
            esize++;
            edg[esize] = { v,w,f };
            nxt[esize] = h[u];
            h[u] = esize;
        }
        int minf[maxn], pre[maxn], inedg[maxn], flow[maxn];
        bool inq[maxn];
        int s, t;
        int mxflow, mncost;
        inline bool spfa()
        {
            for (int i = 1; i <= n; i++)
            {
                minf[i] = inf;
                inq[i] = 0;
                pre[i] = 0;
                flow[s] = INT_MAX;
            }
            queue<int> q;
            q.push(s);
            minf[s] = 0;
            inq[s] = 1;
            while (!q.empty())
            {
                int u = q.front();
                q.pop();
                inq[u] = 0;
                for (int i = h[u]; i; i = nxt[i])
                {
                    int v = edg[i].v;
                    if (edg[i].w > 0 && minf[u] + edg[i].f < minf[v])
                    {
                        minf[v] = minf[u] + edg[i].f;
                        pre[v] = u;
                        inedg[v] = i;
                        flow[v] = mn(flow[u], edg[i].w);
                        if (!inq[v])
                        {
                            q.push(v);
                            inq[v] = 1;
                        }
                    }
                }
            }
            return pre[t];
        }
        void MCMF(int _s, int _t)
        {
            s = _s;
            t = _t;
            mxflow = 0;
            mncost = 0;
            while (spfa())
            {
                int x = t;
                mxflow += flow[t];
                mncost += flow[t] * minf[t];
                while (x != s)
                {
                    int i = inedg[x];
                    edg[i].w -= flow[t];
                    edg[i ^ 1].w += flow[t];
                    x = pre[x];
                }
            }
        }
    }g;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值