bzoj3504_Dangerous bridge

I can see the network flow at a glance, but unfortunately I can't write it... I really couldn't think of a modeling method at that time.

Consider setting a source point to flow to a1 and b1, and then a2 and b2 to flow to another sink point, so that it is enough to determine that the maximum flow is equal to the flow that flows in at the beginning.

Then hehe. If he starts from a1 and runs to b2, Bob can only watch Alice's back walk away and disappear at the other end of the bridge. He is about to step to pursue it, but he finds that his feet are empty. It turns out that the dangerous bridge has already collapsed, and when Alice turns back, Only to find that the man has fallen into the abyss. So Alice handed over the flash... (infinite brain supplement here) In short, in order to maintain the peace of the world, we do not allow such network flow to exist.

The solution is also very simple, just swap the start and end points of Alice or Bob, because if there is a situation where Bob falls to the bottom of the sea, when we meet again in the next life, we will find that the two meet on the same bridge, right? So if you don't have a fate in this life, don't see each other in the next life. It's the truth that everyone goes their own way.

Next is the normal network flow. Since the adjacency matrix is ​​not written, it is still a forward star here.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define N 50 + 3
#define M 5000 + 10
#define INF 1000000000

using namespace std;

struct edge
{
    int to, cap, flow, next;
}e[M];
char ch[N][N];
int n, a1, a2, an, b1, b2, bn, ans;
int s, t, num, p[N], flag[N], d[N], now[N];
void add(int x, int y, int z)
{
    e[++num].to = y;
    e[num].cap = z;
    e[num].next = p[x];
    p[x] = num;
}
void read()
{
    for (int i = 1; i <= n; ++i)
    {
        getchar();
        for (int j = 1; j <= n; ++j)
        ch[i][j] = getchar();
    }
}
void init()
{
    memset(e, 0, sizeof e);
    memset(p, 0, sizeof p);
    num = 1;
    for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j)
    switch(ch[i][j])
    {
        case 'X': break;
        case 'O': add(i, j, 2); add(j, i, 0); break;
        case 'N': add(i, j, INF); add(j, i, 0); break;
    }
}
int dfs(int x, int mini)
{
    if (x == t || !mini) return mini;
    int flow = 0;
    for (int i = now[x]; i; i = e[i].next)
    {
        now[x] = i;
        int k = e[i].to;
        if (d[k] == d[x] + 1)
        {
            int tmp = dfs(k, min(mini, e[i].cap-e[i].flow));
            if (tmp <= 0) continue;
            e[i].flow += tmp;
            e[i^1].flow -= tmp;
            flow += tmp;
            mini -= tmp;
            if (!mini) break;
        }
    }
    return flow;
}
bool bfs(int s, int t)
{
    memset(flag, 0, sizeof flag);
    memset(d, 0, sizeof d);
    queue<int>q;
    q.push(s);
    d[s] = 0;
    flag[s] = 1;
    while(!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = p[x]; i; i = e[i].next)
        {
            int k = e[i].to;
            if (!flag[k] && e[i].cap > e[i].flow)
            {
                flag[k] = 1;
                d[k] = d[x] + 1;
                q.push(k);
            }
        }
    }
    return flag[t];
}
void dinic()
{
    ans = 0;
    while(bfs(s, t))
    {
        for (int i = 0; i <= t; ++i)
        now[i] = p[i];
        ans += dfs(s, INF);
    }
}
int main()
{
    freopen("bridge.in", "r", stdin);
    freopen("bridge.out", "w", stdout);
    while(scanf("%d %d %d %d %d %d %d", &n, &a1, &a2, &an, &b1, &b2, &bn) != EOF)
    {
        read();
        s = 0, t = n + 1;
        ++a1, ++a2, ++b1, ++b2;
        init();
        add(s, a1, 2*an); add(a1, s, 0);
        add(s, b1, 2*bn); add(b1, s, 0);
        add(a2, t, 2*an); add(t, a2, 0);
        add(b2, t, 2*bn); add(t, b2, 0);
        dinic();
        if (ans < 2 * (an+bn))
        {
            printf("No\n");
            continue;
        }
        init();
        add(s, a1, 2*an); add(a1, s, 0);
        add(s, b2, 2*bn); add(b2, s, 0);
        add(a2, t, 2*an); add(t, a2, 0);
        add(b1, t, 2*bn); add(t, b1, 0);
        dinic();
        if (ans < 2 * (an+bn)) printf("No\n");
        else printf("Yes\n");
    }
    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326291767&siteId=291194637