@bzoj - 3504 @ [Cqoi2014] dangerous bridge


@description@

Alice and Bob live in a seat by the N state islands, the islands are numbered 0 to N-1. There are some islands connected between the bridge and road bridge in both directions, but only for one person to pass. Some of the bridge due to the disrepair become dangerous bridge, you can only pass twice. Alice wants to and from an island twice between al and a2 (once again count back and forth from al to a2 from a2 to al). Meanwhile, Bob hope bn times back and forth between the islands bl and b2. This process, all the most dangerous bridge traffic twice, the rest of the bridge unlimited access. Will Alice and Bob to complete their wishes?

Input
this question multiple sets of test data.
The first line of each set contains seven spaces separated integers, respectively, N, al, a2, an, bl, b2, bn.
Next is a symmetric matrix of N rows and N columns, uppercase letters. I row and j column of the matrix number i describe the connections between the islands jl-1 and, if it is "O" indicates that there is danger bridge connected: as "N" represents the ordinary bridge connected: as "X" indicates no bridge connected.

Output
For each set of test data output line, if they desire to be able to complete output "Yes", otherwise a "No".

Sample Input
4 0 1 1 2 3 1
XOXX
OXOX
XOXO
XXOX
4 0 2 1 1 3 2
XNXO
NXOX
XOXO
OXOX
Sample Output
Yes
No

Range data
. 4 <= N <50
O <= A1, A2, B1, B2 <-N =. 1
. 1 <= AN. B <= 50

@solution@

[Bzoj title face. . . I'm not any good Tucao. . . ]

Beginning to worship the details of the chiefs of the blog, relevant evidence in great detail orz .

This question is actually a match between the sink and the source of multi-source multi-sink maximum flow fixed.
Can be relatively easily think of such an idea: build a super source connected a1, b1, the a2, b2 and even sink to the super capacity were set to 2 AN 2 and BN; capacity to the dangerous bridge 2, the normal bridge capacity is set to inf, even as a two-way side.
After such maximum flow built FIG run, if the maximum flow = 2 * (an + bn) is solvable.
Because all the edges of the capacity of all even numbers (inf can be used as an even number), so you can put all the capacity divided by two to determine the maximum flow is equal to an + bn (ie the Internet said just need to be seen as a single round-trip).

But it can be found if a1 -> b2 and b1 -> a2, the maximum flow ran out of "solvability" not necessarily really solvable.
Another point number, is to limit the dangerous bridge back and forth add up <= 1, but we build out of the map corresponds to the positive direction and the opposite direction respectively <= 1.

We only need to source s connected a1, b2, the a2, b1 and even sink t, maximum flow run again, it can be determined whether or not legitimate.
As for proof. . . The above said essay blog speaks very goodSo I'll just stick around a

If the full flow and there is still a problem that happens then? Draw a map.
The first run is assumed that the maximum flow, the flow rate a1 → b2 is x, then the flow b1 → b2 to bn-x, also flow b1 → a2 x, a1 → a2 flow is an-x.
Run while the second maximum flow, because it is no, a1 → b2 → b1 and a2 flow may change the view or an-x, bn-x. So a1 → b1 and b2 → a2 flow (Note: The original blogger this place is wrong, in the comments section below mentioned) are also still x.
And these two shows what, a1 b1 x traffic can flow can also flow b2 x flow without affecting traffic between a1 and a2, b1 and b2.
Because it is undirected graph, the reverse flow rate a1 → b1, flow rate can be obtained in b1 → b2 x. b1, b2 will flow between the legitimate. Similarly a1, a2 can flow between the legitimate.
So if the exchange b1, b2 is still full flow, certainly not a problem that situation exists.

For two problems, if a1 → a2 after a dangerous bridge forward, reverse and b1 → b2 after the bridge, the swap b1, b2, b2 is in the starting point, a1 → a2, b2 → b1 two paths are forward through this edge, it has been limited traffic.
So if still full flow, there is no question two.

@accepted code@

#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 50;
const int MAXV = MAXN;
const int MAXE = 2*MAXV*MAXV;
const int INF = int(1E6);
struct FlowGraph{
    struct edge{
        int to, cap, flow;
        edge *nxt, *rev;
    }edges[MAXE + 5], *adj[MAXV + 5], *cur[MAXV + 5], *ecnt;
    int s, t, n;
    void clear(int _n) {
        n = _n; ecnt = &edges[0];
        for(int i=0;i<=n;i++)
            adj[i] = NULL;
    }
    void addedge(int u, int v, int c) {
        edge *p = (++ecnt), *q = (++ecnt);
        p->to = v, p->cap = c, p->flow = 0;
        p->nxt = adj[u], adj[u] = p;
        q->to = u, q->cap = 0, q->flow = 0;
        q->nxt = adj[v], adj[v] = q;
        p->rev = q, q->rev = p;
//      printf("%d %d %lld\n", u, v, c);
    }
    queue<int>que; int d[MAXV + 5];
    bool relabel() {
        for(int i=0;i<=n;i++)
            cur[i] = adj[i], d[i] = n + 5;
        while( !que.empty() ) que.pop();
        d[t] = 0, que.push(t);
        while( !que.empty() ) {
            int f = que.front(); que.pop();
            for(edge *p=adj[f];p;p=p->nxt)
                if( d[f] + 1 < d[p->to] && p->rev->cap > p->rev->flow ) {
                    d[p->to] = d[f] + 1;
                    que.push(p->to);
                    if( p->to == s ) return true;
                }
        }
        return !(d[s] == n + 5);
    }
    int aug(int x, int tot) {
        if( x == t ) return tot;
        int sum = 0;
        for(edge *&p=cur[x];p;p=p->nxt) {
            if( p->cap > p->flow && d[p->to] + 1 == d[x] ) {
                int del = aug(p->to, min(p->cap - p->flow, tot - sum));
                p->flow += del, p->rev->flow -= del, sum += del;
                if( sum == tot ) break;
            }
        }
        return sum;
    }
    int max_flow(int _s, int _t) {
        s = _s, t = _t; int flow = 0;
        while( relabel() )
            flow += aug(s, INF);
        return flow;
    }
}G;
int N, a1, a2, an, b1, b2, bn;
char str[MAXN + 5][MAXN + 5];
int main() {
    while( scanf("%d%d%d%d%d%d%d", &N, &a1, &a2, &an, &b1, &b2, &bn) == 7 ) {
        bool flag = true;
        for(int i=0;i<N;i++)
            scanf("%s", str[i]);
        G.s = N, G.t = N + 1;
        G.clear(N + 2);
        for(int i=0;i<N;i++)
            for(int j=0;j<N;j++)
                if( str[i][j] == 'O' ) G.addedge(i, j, 1);
                else if( str[i][j] == 'N' ) G.addedge(i, j, INF);
        G.addedge(G.s, a1, an), G.addedge(G.s, b1, bn);
        G.addedge(a2, G.t, an), G.addedge(b2, G.t, bn);
        flag &= (G.max_flow(G.s, G.t) == an + bn);
        G.s = N, G.t = N + 1;
        G.clear(N + 2);
        for(int i=0;i<N;i++)
            for(int j=0;j<N;j++)
                if( str[i][j] == 'O' ) G.addedge(i, j, 1);
                else if( str[i][j] == 'N' ) G.addedge(i, j, INF);
        G.addedge(G.s, a1, an), G.addedge(G.s, b2, bn);
        G.addedge(a2, G.t, an), G.addedge(b1, G.t, bn);
        flag &= (G.max_flow(G.s, G.t) == an + bn);
        if( flag ) puts("Yes");
        else puts("No");
    }
}

@details@

I heard that multi-source multiple sinks and sinks stationary sources only problem with linear programming solution.This question is probably because it is very special (2 source 2 sinks).

This conclusion always felt very title of the gods, the field is not what we mere mortals can contact.
I heard moved from topcoder title.

Guess you like

Origin www.cnblogs.com/Tiw-Air-OAO/p/11416181.html