BZOJ 3504 CQOI Dangerous Bridge

3504: [Cqoi2014] Dangerous Bridge

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1882  Solved: 951
[Submit][Status][Discuss]

Description

Alice and Bob live in a country consisting of N islands, numbered 0 to N-1. Some islands are connected by bridges, and the roads on the bridges are
two-way , but only one person can travel at a time. Some of these bridges are in danger of being in disrepair and can only be crossed twice at most. Alice wants to make an round trip between the islands al and a2 (one round trip from al to a2 and then from a2 to al). At the same time, Bob wants to make bn round trips between islands bl and b2. During this process, all dangerous bridges can be passed at most twice, and the remaining bridges can be passed unlimited times. Can Alice and Bob fulfill their wishes?

Input


There are multiple sets of test data for this question.
The first line of each set of data contains 7 integers separated by spaces, which are N, al, a2, an, bl, b2, and bn.
Next is a symmetric matrix with N rows and N columns, consisting of capital letters. The i row and j column of the matrix describe the connection between the islands numbered i-1 and jl. If it is "O", it means that there is a dangerous bridge connected; if it is "N", it means that there is an ordinary bridge connection; if it is "X", it means there is no bridge. connected.
|

Output

Output one line for each set of test data, output "Yes" if they can fulfill the wish, and "No" otherwise.

 

 

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
数据范围
4<=N<50
O<=a1, a2, b1, b2<=N-1
1 <=an. b<=50

HINT

 

Source

 

found a good proof

 

Analysis: This question actually looks like a (harmonious) question at first glance, and then I found that Shui Shui was WA after writing it, and then I downloaded the data from the Internet to observe the data, and found that my WA places were all in the same place, and then I went to the Looking at other people's postures on the Internet, I understand this question.

After reading the question first, I was caught by this round trip for a while at first glance. Later, I found out that if there is a dangerous bridge between A and B, then you will go back and forth at most once, that is, the corresponding traffic is 1. In this case, because there is no direction, there must be a road from B to A with a flow of 1. You can understand it by adding some details and drawing a picture by yourself.

Next, I thought this question was over, so I wrote it and found WA!

Later, through my personal test data, I found that sometimes the traffic flow from a1 to a2 is not what I hoped, and some cases of full flow actually flow from a1 to b2, what should I do?

Then there is a way to solve the problem, that is, after running the first maximum flow, if it is full, then rebuild the map, in which the part of the bridge remains unchanged, the part from the source point to a1, a2 to the sink point remains unchanged, just need Change the original source point to b1, b2 to the sink point to the source point to b2, b1 to the sink point, and then judge again, if the flow is still full, there is a solution.

Unfortunately, I didn't find a proof, so I wrote a proof myself, I don't know its rigor.

After the first full flow

Suppose a1->a2 flow is an-x

a1->b2 flow is x

b1->a2 flow is x

b1->b2 flow is bn-x

Then we assume that the full flow is reached after the second run.

Then a1->a2 flow is still an-x

∴a1->b1 flow is x

b2->a2 flow is x

b2->b1 traffic is bn-x

And the previous a1->b2 flow is x

∴ a1->b2->b1 flow is x (undirected graph)

Then b2->b1 can have a road with a flow of x

And b2->b1 already has a road with traffic bn-x

∴b2->b1 has a road with flow bn

Then a1->a2 has a road with flow an

certified

So just follow this idea and run the maximum flow again.

 

#include <bits/stdc++.h>
#define ll long long
#define inf 1e9+10
using namespace std;
inline int read(){
	int x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
const int MAXN=1e5+10;
struct node{
	int y,next,linkk,flow,back;
}e[MAXN];
int linkk[MAXN],level[100],q[MAXN],head,tail,len,n,s,t,a1,a2,b1,b2,an,bn,col[60][60];
inline void insert(int x,int y,int f){
	e [++ len] .y = y; e [len] .next = linkk [x]; linkk [x] = len; e [len] .back = len + 1; e [len] .flow = f;
	e [++ len] .y = x; e [len] .next = linkk [y]; linkk [y] = len; e [len] .back = len-1; e [len] .flow = 0;
}
inline bool getlevel(){
	head=tail=0;
	memset(level,-1,sizeof(level));
	level[s]=0;q[++tail]=s;
	while(head<tail){
		int tn=q[++head];
		for(int i=linkk[tn];i;i=e[i].next){
			if(level[e[i].y]==-1&&e[i].flow){
				level[e[i].y]=level[tn]+1;
				q[++tail]=e[i].y;
			}
		}
	}
	return level[t]>=0;
}
inline int getmaxflow(int x,int flow){
	if(x==t) return flow;
	int f=0,d;
	for(int i=linkk[x];i;i=e[i].next){
		if(e[i].flow&&level[e[i].y]==level[x]+1){
			if(d=getmaxflow(e[i].y,min(flow-f,e[i].flow))){
				f+=d;e[i].flow-=d;e[e[i].back].flow+=d;
				if(f==flow) return f;
			}
		}
	}
	if(f==0) level[x]=-1;
	return f;
}
inline int dinic(){
	int ans=0,d;
	while(getlevel()){
		while(d=getmaxflow(s,inf)) ans+=d;
	}
	return ans;
}
void build(){
	memset (Linkk, 0, sizeof (Linkk)); len = 0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(col[i][j]==1) insert(i,j,inf);
			if(col[i][j]==0) insert(i,j,1);
		}
	}
}
int main(){
	while(scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF){
		a1++,b1++,a2++,b2++;
		s=0;t=n+1;
	    for(int i=1;i<=n;i++){
		    char ch[60];
		    scanf("%s",ch+1);
		    for(int j=1;j<=n;j++){
			    if(ch[j]=='O') col[i][j]=0;
			    if(ch[j]=='X') col[i][j]=-1;
			    if(ch[j]=='N') col[i][j]=1;
		    }
	    }
	    int flag=0;
		build();
	    insert(s,a1,an),insert(s,b1,bn);
	    insert(a2,t,an),insert(b2,t,bn);
	    int ans=dinic();
	    if(ans<an+bn) flag=1;
	    if(flag){
	    	printf("No\n");continue;
		}
		build();
		insert(s,a1,an);insert(s,b2,bn);
		insert(a2,t,an);insert(b1,t,bn);
		ans=dinic();
		if(ans<an+bn) flag=1;
		if(flag) printf("No\n");
		else printf("Yes\n");
	}
	return 0;
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325134438&siteId=291194637