[BZOJ 3504] [Cqoi2014] dangerous bridge, bzojcqoi2014
3504: [Cqoi2014] critical bridge
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 583 Solved: 309
[Submit] [Status] [Discuss]
Description
Alice and Bob reside 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 double
Forward, but only one person can pass at a time. Some of these bridges become dangerous because they are out of service for a long time. They can only be used twice at most. Alice wants to make a round trip between the island al AND a2 (from al to a2 and then from a2 to al ). At the same time, Bob wants to make a round trip to bn between the island bl and b2. In this process, all dangerous bridges can be used for a maximum of two times, and other bridges can be used for unlimited traffic. Can Alice and Bob fulfill their wishes?
Input
This question contains multiple groups of test data.
The first row of each data group contains seven integers separated by spaces: N, al, a2, an, bl, b2, and bn.
Next is a symmetric matrix of N rows and N columns consisting of uppercase letters. The j column of the I row of the matrix describes the connection between the islands numbered I 1 and j-l. If it is "O", it indicates that a dangerous bridge is connected: "N" indicates a normal Bridge Connection: "X" indicates no bridge connection.
|
Output
Output a row of test data for each group. If they can complete the desire, output "Yes"; otherwise, output "No ".
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
Data range
4 <= N <50
O <= a1, a2, b1, b2 <= N-1
1 <= an. B <= 50
Network Flow.
If we directly create a network flow S Streams from two starting points 2 branch an, 2 branch bn Traffic, end S Various streams 2 branch an, 2 branch bn Between the point and the point according to the read flow, will appear from A1 Flow B2 , B1 Flow A2 In this case, the stream is full.
How can this problem be solved?
Set B1, b2 Switch to see if the stream is still full.
The following describes the proof of the official question (I cannot fully understand it yet = ):
Assume that the first time you run the network stream a1 to a2 An −x , A1 to b2 stream X , B1 to b2 stream Bn −x , B1 to a2 stream X
After the exchange, because it is an undirected graph, a1 to a2 can still flow An −x , B2 to b1 can still flow Bn −x .
At this time, because the stream is still full, a1 to b1 streams X , B2 to a2 stream X .
The first a1 to B2. X , Second a1 to b1 stream X ;
Because it is an undirected graph, we reverse the edge to b1 to a1 stream. X , A1 to b2 stream X This is equivalent to the b1-b2 stream. X Add the first time b1 to b2 Bn −x B1 to b2 does stream bn (same as)
What I don't understand is that the second full stream of a1 to a2 can flow. An −x But not necessarily stream An −x Maybe there are fewer or more streams for full stream.
#include <iostream>#include <algorithm>#include <cstring>#include <cmath>#include <cstdio>#include <cstdlib>#include <queue>#define inf 0x3f3f3f3fusing namespace std;char S[55][55];int d[55],v[55],cur[55],tot,s,t,h[55],n,a1,a2,an,b1,b2,bn;struct edge{ int from,to,cap,flow,ne;}E[100005];void Addedge(int from,int to,int cap){ E[++tot]=(edge){from,to,cap,0,h[from]}; h[from]=tot; E[++tot]=(edge){to,from,0,0,h[to]}; h[to]=tot;}void Build(){ tot=1; for (int i=s;i<=t;i++) h[i]=0; for (int i=1;i<=n;i++) for (int j=0;j<n;j++) { if (S[i][j]=='O') Addedge(i,j+1,2); if (S[i][j]=='N') Addedge(i,j+1,inf); }}bool bfs(){ for (int i=s;i<=t;i++) v[i]=0; queue<int> q; q.push(s); v[s]=1; d[s]=0; while (!q.empty()) { int x=q.front(); q.pop(); for (int i=h[x];i;i=E[i].ne) { edge e=E[i]; if (!v[e.to]&&e.cap>e.flow) { v[e.to]=1; d[e.to]=d[x]+1; q.push(e.to); } } } return v[t];}int dfs(int x,int a){ if (x==t||!a) return a; int flow=0; for (int &i=cur[x];i;i=E[i].ne) { edge &e=E[i]; if (d[e.to]!=d[x]+1) continue; int f=dfs(e.to,min(a,e.cap-e.flow)); if (f>0) { e.flow+=f; E[i^1].flow-=f; flow+=f; a-=f; if (!a) break; } } return flow;}int dinic(){ int flow=0; while (bfs()) { for (int i=s;i<=t;i++) cur[i]=h[i]; flow+=dfs(s,inf); } return flow;}int main(){ while (scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF) { s=0,t=n+1; for (int i=1;i<=n;i++) scanf("%s",S[i]); an*=2,bn*=2; a1++,a2++,b1++,b2++; Build(); Addedge(s,a1,an),Addedge(a2,t,an); Addedge(s,b1,bn),Addedge(b2,t,bn); if (dinic()==an+bn) { Build(); Addedge(s,a1,an),Addedge(a2,t,an); Addedge(s,b2,bn),Addedge(b1,t,bn); if (dinic()==an+bn) puts("Yes"); else puts("No"); } else puts("No"); } return 0;}
Perception:
1. TLE does not write v [s] = 1 in bfs.
2. CQOI2014