• Marriage Match IV---hdu3416(spfa + Dinic)


    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3416

    有一个有向图,n个点,m条边,给一个起点和终点,求出从起点到终点的最短路共有几条,每条路只能走一次,每个点可以走多次;

    先用spfa求出从起点到各点的距离dist,然后根据dist的值建立新的图,边权为1,套用Dinic模板求起点到终点的最大流即可;

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <queue>
    #include <stack>
    #include <algorithm>
    #include <map>
    #include <string>
    typedef long long LL;
    #define INF 0x3f3f3f3f
    #define met(a, b) memset(a, b, sizeof(a))
    #define N 200005
    
    using namespace std;
    
    struct node
    {
        int v, w, Next;
    }G[N], e[N];
    
    
    
    int n, m, dist[N], vis[N], A, B;
    int l[N];
    
    int Head[N], cnt;
    void Add(int u, int v, int w)
    {
        G[cnt].v = v;
        G[cnt].w = w;
        G[cnt].Next = Head[u];
        Head[u] = cnt++;
    }
    
    int Head1[N], cnt1;
    void Add1(int u, int v, int w)
    {
        e[cnt1].v = v;
        e[cnt1].w = w;
        e[cnt1].Next = Head1[u];
        Head1[u] = cnt1++;
    }
    
    void spfa()
    {
        for(int i=1; i<=n; i++)
            dist[i] = INF;
        met(vis, 0);
        queue<int>Q;
        Q.push(A);
        vis[A] = 1;
        dist[A] = 0;
        while(!Q.empty())
        {
            int p = Q.front();Q.pop();
            vis[p] = 0;
            for(int i=Head[p]; i!=-1; i=G[i].Next)
            {
                int q = G[i].v;
                if(dist[q] > dist[p]+G[i].w)
                {
                    dist[q] = dist[p]+G[i].w;
                    if(!vis[q])
                    {
                        vis[q] = 1;
                        Q.push(q);
                    }
                }
            }
        }
    }
    
    bool bfs(int s, int End)
    {
        met(l, 0);
        queue<int>Q;
        Q.push(s);
        l[s] = 1;
        while(!Q.empty())
        {
            int u = Q.front();Q.pop();
            if(u == End)return true;
            for(int i=Head1[u]; i!=-1; i=e[i].Next)
            {
                int v = e[i].v;
                if(!l[v] && e[i].w)
                {
                    l[v] = l[u]+1;
                    Q.push(v);
                }
            }
        }
        return false;
    }
    
    int dfs(int u, int MaxFlow, int End)
    {
        if(u == End)return MaxFlow;
    
        int uflow = 0;
    
        for(int j=Head1[u]; j!=-1; j=e[j].Next)
        {
            int v = e[j].v;
            if(l[v]==l[u]+1 && e[j].w)
            {
                int flow = min(e[j].w, MaxFlow-uflow);
                flow = dfs(v, flow, End);
                e[j].w -= flow;
                e[j^1].w += flow;
                uflow += flow;
                if(uflow == MaxFlow)
                    break;
            }
        }
        if(uflow == 0)
            l[u] = 0;
        return uflow;
    }
    
    int Dinic()
    {
        int MaxFlow = 0;
        while(bfs(A, B))
            MaxFlow += dfs(A, INF, B);
        return MaxFlow;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            met(Head, -1);
            cnt = 0;
            met(Head1, -1);
            cnt1 = 0;
    
            scanf("%d %d", &n, &m);
    
            for(int i=1; i<=m; i++)
            {
                int u, v, w;
                scanf("%d %d %d", &u, &v, &w);
                if(u == v)continue;
                Add(u, v, w);
            }
            scanf("%d %d", &A, &B);
    
            spfa();///更新dist;
    
            for(int i=1; i<=n; i++)
            {
                for(int j=Head[i]; j!=-1; j=G[j].Next)
                {
                    int v = G[j].v;
                    if(dist[v] == dist[i]+G[j].w)///建立新的网络流图;
                    {
                        Add1(i, v, 1);
                        Add1(v, i, 0);
                    }
                }
            }
    
            int ans = Dinic();///求最大流即可;
    
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    windows下命令行
    利用border画三角形
    正则
    flex布局
    css笔记
    W3C标准
    SEO相关
    左边固定,右边自适应(解决方案)
    容错性测试的测试点
    Charles安装及使用教程
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5829830.html
Copyright © 2020-2023  润新知