【LOJ】#2239. 「CQOI2014」危桥

LOJ#2239. 「CQOI2014」危桥

就是先把每条边正着连一条容量为2的边,反着连一条容量为2的边

显然如果只有一个人走的话,答案就是一个源点往起点连一条容量为次数×2的边,终点往汇点连一个次数×2的边,跑最大流看是否满流即可

两个人的话由于两个人的路径可能相交,有可能从\(a_1\)走到了\(b_2\)

统计一遍 \(a_1,b_{1}\)为源点,\(a_{2},b_{2}\)为汇点的情况

再统计一遍\(a_{1},b_{2}\)为源点,\(a_{2},b_{1}\)为汇点的情况

这两种都合法的话才能证明可以走到

#include 
#define fi first
#define se second
#define pii pair
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define ba 47
#define MAXN 1005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
int a[3],b[3];
int S,T,dis[55];
char g[55][55];
struct node {
    int to,next,cap;
}E[100005];
int head[55],sumE = 1;
void add(int u,int v,int c) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    E[sumE].cap = c;
    head[u] = sumE;
}
void addtwo(int u,int v,int c) {
    add(u,v,c);add(v,u,0);
}
queue Q;
bool BFS() {
    Q.push(S);
    memset(dis,0,sizeof(dis));
    dis[S] = 1;
    while(!Q.empty()) Q.pop();
    Q.push(S);
    while(!Q.empty()) {
    int u = Q.front();Q.pop();
    if(u == T) return true;
    for(int i = head[u] ; i;  i = E[i].next) {
        int v = E[i].to;
        
        if(E[i].cap > 0 && !dis[v]) {
        dis[v] = dis[u] + 1;
        if(v == T) return true;
        Q.push(v);
        
        }
    }
    }
    return dis[T] != 0;
}
int dfs(int u,int aug) {
    if(u == T) return aug;
    int flow = 0;
    for(int i = head[u] ; i; i = E[i].next) {
    int v = E[i].to;
    if(dis[v] == dis[u] + 1) {
        int t = dfs(v,min(aug - flow,E[i].cap));
        flow += t;
        E[i].cap -= t;
        E[i ^ 1].cap += t;
        if(flow == aug) return flow;
    }
    }
    return flow;
}
int Dinic() {
    int res = 0;
    while(BFS()) {
    while(int d = dfs(S,1e9)) {
        res += d;
    }
    }
    return res;
}
void create() {
    sumE = 1;memset(head,0,sizeof(head));
    for(int i = 1 ; i <= N ; ++i) {
    for(int j = 1 ; j <= N ; ++j) {
        if(g[i][j] == 'N') addtwo(i,j,1e9);
        else if(g[i][j] == 'O') addtwo(i,j,2);
    }
    }
}
bool Process() {
    create();
    addtwo(S,a[0],2 * a[2]);
    addtwo(S,b[0],2 * b[2]);
    addtwo(a[1],T,2 * a[2]);
    addtwo(b[1],T,2 * b[2]);
    return Dinic() >= 2 * (a[2] + b[2]);
}
void Solve() {
    for(int i = 0 ; i < 3 ; ++i) read(a[i]);
    ++a[0];++a[1];
    for(int i = 0 ; i < 3 ; ++i) read(b[i]);
    ++b[0];++b[1];
    for(int i = 1 ; i <= N ; ++i) scanf("%s",g[i] + 1);
    S = N + 1;T = N + 2;
    bool f = 1;
    f &= Process();
    swap(b[0],b[1]);
    f &= Process();
    if(f) puts("Yes");
    else puts("No");
}
int main(){
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    while(scanf("%d",&N) != EOF) {
    Solve();
    }
}

转载于:https://www.cnblogs.com/ivorysi/p/10999597.html

你可能感兴趣的:(【LOJ】#2239. 「CQOI2014」危桥)