• 网络流练习


    NC19931 危桥  

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 55;
    const int INF = 0x3f3f3f3f;
    struct edge
    {
        int to, cap, rev;            //rev记录对应反向边在对应邻接表的下标
        edge(int k1, int k2, int k3): to{k1}, cap{k2}, rev{k3} {}
    };
    
    struct flow
    {
        vector<edge> G[maxn];
        int level[maxn], iter[maxn];       //level记录bfs时与s的距离,iter记录当前弧
    
        void add_edge(int from, int to, int cap)
        {
            //cout << from << ' ' << to << ' ' << cap << endl;
            G[from].push_back((edge){to, cap, (int)G[to].size()});
            G[to].push_back((edge){from, 0, (int)G[from].size()-1});
        }
    
        void bfs(int s, int t)
        {
            queue<int> que;
            memset(level, -1, sizeof(level));
            level[s] = 0;
            que.push(s);
            while(!que.empty())
            {
                int v = que.front(); que.pop();
                for(int i = 0; i < G[v].size(); i++)
                {
                    edge &e = G[v][i];
                    if(e.cap > 0 && level[e.to] < 0)    //其可达并且第一次到达
                    {
                        level[e.to] = level[v] + 1;
                        if(e.to == t) return;
                        que.push(e.to);
                    }
                }
            }
        }
    
        int dfs(int v, int t, int f)             //从v到t的最大流
        {
            if(v == t) return f;
            for(int &i = iter[v]; i < G[v].size(); i++)        //弧优化
            {
                edge &e = G[v][i];
                if(e.cap > 0 && level[v] < level[e.to])        //可达并且是下一层
                {
                    int d = dfs(e.to, t, min(f, e.cap));
                    if(d > 0)
                    {
                        e.cap -= d;
                        G[e.to][e.rev].cap += d;
                        return d;
                    }
                }
            }
            return 0;
        }
    
        int max_flow(int s, int t)
        {
            int flow = 0, f;
            for(;;)
            {
                bfs(s, t);                //首先bfs构造分层图
                if(level[t] < 0) return flow;          //t不可达直接退出
                memset(iter, 0, sizeof(iter));
                while((f = dfs(s, t, INF)) > 0)        //每次增加一条最短增广路
                    flow += f;
            }
        }
    
    }f, g;
    
    int main()
    {
        int n, a1, a2, an, b1, b2, bn;
        char c;
        while(scanf("%d %d %d %d %d %d %d", &n, &a1, &a2, &an, &b1, &b2, &bn) == 7)
        {
            for(int i = 0; i < maxn; ++i) f.G[i].clear();
            memset(f.level, 0, sizeof(f.level)); memset(f.iter, 0, sizeof(f.iter));
            for(int i = 0; i < maxn; ++i) g.G[i].clear();
            memset(g.level, 0, sizeof(g.level)); memset(g.iter, 0, sizeof(g.iter));
            for(int i = 0; i < n; ++i)
                for(int j = 0; j < n; ++j)
                {
                    scanf(" %c", &c);
                    if(c == 'N')
                        f.add_edge(i, j, INF);
                    else if(c == 'O')
                        f.add_edge(i, j, 2);
                }
            g = f;
            int s = n, t = n + 1;
            f.add_edge(s, a1, 2 * an), f.add_edge(s, b1, 2 * bn);
            f.add_edge(a2, t, 2 * an), f.add_edge(b2, t, 2 * bn);
    
            g.add_edge(s, a1, 2 * an), g.add_edge(s, b2, 2 * bn);
            g.add_edge(a2, t, 2 * an), g.add_edge(b1, t, 2 * bn);
            if(f.max_flow(s, t) == 2 * an + 2 * bn && g.max_flow(s, t) == 2 * an + 2 * bn) printf("Yes
    ");
            else printf("No
    ");
        }
    }
  • 相关阅读:
    在线免费学习全世界的课程
    【安卓】imageView.scaleType取centerCrop后,再用padding时显示异常?
    win8+VS2012搭建OpenGL超级宝典的环境
    leetcode第一刷_Plus One
    HASH JION AND NESTED JION
    Hive创建外部表以及分区
    Android数字签名解析(一)
    Alex 的 Hadoop 菜鸟教程: 第3课 Hadoop 安装教程
    用C#生成不反复的随机数
    Swift数据类型及数据类型转换
  • 原文地址:https://www.cnblogs.com/Maxx-el/p/14152998.html
Copyright © 2020-2023  润新知