就是先把每條邊正着連一條容量爲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(); } }