【LOJ】#2239. 「CQOI2014」危橋

LOJ#2239. 「CQOI2014」危橋

就是先把每條邊正着連一條容量爲2的邊,反着連一條容量爲2的邊node

顯然若是隻有一我的走的話,答案就是一個源點往起點連一條容量爲次數×2的邊,終點往匯點連一個次數×2的邊,跑最大流看是否滿流便可c++

兩我的的話因爲兩我的的路徑可能相交,有可能從\(a_1\)走到了\(b_2\)spa

統計一遍 \(a_1,b_{1}\)爲源點,\(a_{2},b_{2}\)爲匯點的狀況code

再統計一遍\(a_{1},b_{2}\)爲源點,\(a_{2},b_{1}\)爲匯點的狀況get

這兩種都合法的話才能證實能夠走到it

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#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<class T>
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<class T>
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<int> 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();
    }
}
相關文章
相關標籤/搜索