网络流练习

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\n");
        else printf("No\n");
    }
}

 

posted @ 2020-12-18 01:30  .Ivorelectra  阅读(95)  评论(0编辑  收藏  举报