【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 <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('
')
#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();
    }
}
原文地址:https://www.cnblogs.com/ivorysi/p/10999597.html