• poj 1273 Drainage Ditches (网络流 最大流)


      网络流模板题。

    ==========================================================================================================

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef long long LL;
    const LL INF = 1e9+7;
    const LL maxn = 1005;
    const LL MOD = 1e9+7;
    int n, m, Head[maxn], k;
    int Pre[maxn];
    bool vis[maxn];
    struct Edge
    {
        int from, to, w;
        int next;
    }edge[maxn*2];
    
    void Init()
    {
        memset(Head, -1, sizeof(Head));
        memset(Pre, -1, sizeof(Pre));
    }
    void AddEdge(int s,int e,int w)
    {
        edge[k].from = s;
        edge[k].to = e;
        edge[k].w = w;
        edge[k].next = Head[s];
        Head[s] = k ++;
    }
    bool BFS(int s,int e)///从源点到汇点找到一条路径
    {
        memset(vis, false, sizeof(vis));
        queue<int> Q;
        Q.push(s);
        Pre[s] = -1;
        vis[s] = true;
        while( Q.size() )
        {
            int v = Q.front();
            Q.pop();
            if(v == e) return true;
    
            for(int i=Head[v]; i != -1; i = edge[i].next)
            {
                int to = edge[i].to;
                if( !vis[to] && edge[i].w )
                {
                    vis[to] = true;
                    Pre[to] = i;
                    Q.push(to);
                }
            }
        }
        return false;
    }
    
    int Karp(int s,int e)
    {
        int ans = 0;
        while( BFS(s, e) )///如果能找到路径就一直找
        {
            int MinFlow = INF, Cur = Pre[e];
    
            while(Cur != -1)
            {
                MinFlow = min(MinFlow, edge[Cur].w);
                Cur = Pre[edge[Cur].from];
            }
            ans += MinFlow;
            Cur = Pre[e];
    
            while(Cur != -1)
            {
                edge[Cur].w -= MinFlow;
                edge[Cur^1].w += MinFlow;
                Cur = Pre[edge[Cur].from];
            }
        }
        return ans;
    }
    
    
    int main()
    {
        while(cin >> m >> n)
        {
            int s, e, w;
            Init();
            for(int i=0; i<m; i++)
            {
                scanf("%d %d %d", &s, &e, &w);
                AddEdge(s, e, w);
                AddEdge(e, s, 0);///增加的反向边
            }
    
            printf("%d
    ", Karp(1, n) );
        }
        return 0;
    }

    ==========================================================================================================

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef long long LL;
    const LL INF = 1e9+7;
    const LL maxn = 1005;
    const LL MOD = 1e9+7;
    int n, m, Head[maxn], k;
    int Depth[maxn];
    bool vis[maxn];
    struct node
    {
        int s, e, flow;
        int next;
    }edge[maxn*2];
    
    void AddEdge(int s,int e,int flow)
    {
        edge[k].s = s;
        edge[k].e = e;
        edge[k].flow = flow;
        edge[k].next = Head[s];
        Head[s] = k ++;
    }
    
    
    bool BfsDepth(int Star,int End)
    {
        memset(Depth, 0, sizeof(Depth) );
        queue<int> Q;
        Depth[Star] = 1;
        Q.push(Star);
    
        while( Q.size() )
        {
            int s = Q.front();
            Q.pop();
            if(s == End) return true;
    
            for(int i=Head[s]; i != -1; i=edge[i].next)
            {
                int e = edge[i].e;
                if(!Depth[e] && edge[i].flow)
                {
                    Q.push(e);
                    Depth[e] = Depth[s] + 1;
                }
            }
        }
        return false;
    }
    
    int DFS(int s,int MaxFlow)///从s点发出的最大流量是MaxFlow
    {
        if(s == n) return MaxFlow;
        int sFlow = 0;///sFlow 从
    
        for(int i=Head[s]; i != -1; i = edge[i].next)
        {
            int e = edge[i].e, flow = edge[i].flow;
    
            if(Depth[s]+1 == Depth[e] &&  flow)///到达下一层
            {
                flow = min(MaxFlow-sFlow, flow);
                flow = DFS(e, flow);
                edge[i].flow -= flow;
                edge[i^1].flow += flow;
                sFlow += flow;
                if(sFlow == MaxFlow)
                    break;
            }
        }
        if(sFlow == 0)
            Depth[s] = 0;
        return sFlow;
    }
    
    
    int Dinic(int s,int e)
    {
        int ans = 0;
        while(BfsDepth(s,e) == true)
        {
            ans += DFS(s, INF);
        }
        return ans;
    }
    
    int main()
    {
        while(scanf("%d %d",&m, &n) != EOF)
        {
            int s, e, w;
            memset(Head, -1, sizeof(Head));
            k = 0;
            for(int i=0; i<m; i++)
            {
                scanf("%d %d %d", &s, &e, &w);
                AddEdge(s, e, w);
                AddEdge(e, s, 0);///添加反向边
            }
            printf("%d
    ", Dinic(1, n) );
        }
        return 0;
    }
  • 相关阅读:
    如何查看openssl支持的所有TLS/SSL版本
    讲故事,学(AHK)设计模式—观察者模式
    React Hooks 详解 【近 1W 字】+ 项目实战
    为什么要在函数组件中使用React.memo?
    js防抖函数
    JS 深度优先遍历与广度优先遍历 实现查找
    你不知道的 requestIdleCallback
    RE:ゼロから始める文化課生活
    开学考小记 & 新生活的开始
    JS中:数组和对象的区别,以及遍历数组和遍历对象的区别
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4849808.html
Copyright © 2020-2023  润新知