Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。某些岛屿之间有桥相连,桥上的道路是双
向的,但一次只能供一人通行。其中一些桥由于年久失修成为危桥,最多只能通行两次。Alice希望在岛屿al和a2之间往返an次(从al到a2再从a2到al算一次往返)。同时,Bob希望在岛屿bl和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。请问Alice和Bob能完成他们的愿望吗?
Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。某些岛屿之间有桥相连,桥上的道路是双
向的,但一次只能供一人通行。其中一些桥由于年久失修成为危桥,最多只能通行两次。Alice希望在岛屿al和a2之间往返an次(从al到a2再从a2到al算一次往返)。同时,Bob希望在岛屿bl和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。请问Alice和Bob能完成他们的愿望吗?
本题有多组测试数据。
每组数据第一行包含7个空格隔开的整数,分别为N、al、a2、an、bl、b2、bn。
接下来是一个N行N列的对称矩阵,由大写字母组成。矩阵的i行j列描述编号i一1和j-l的岛屿间的连接情况,若为“O”则表示有危桥相连:为“N”表示有普通的桥相连:为“X”表示没有桥相连。
|
对于每组测试数据输出一行,如果他们都能完成愿望输出“Yes”,否则输出“No”。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define N 10000 #define M 200000 using namespace std; int m,n,a1,a2,an,b1,b2,bn; int point[N],next[M*2],remain[M*2]; int v[M*2],a[300][300],maxflow,tot,last[N],deep[N],cur[N],num[N]; const int inf=1e9; void clear() { tot=-1; memset(point,-1,sizeof(point)); memset(next,-1,sizeof(next)); memset(num,0,sizeof(num)); } void add(int x,int y,int z) { tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; remain[tot]=z; tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x; remain[tot]=0; } void build() { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (a[i][j]) add(1+i,1+j,a[i][j]); } int addflow(int s,int t) { int now=t; int ans=inf; while(now!=s) { ans=min(ans,remain[last[now]]); now=v[last[now]^1]; } now=t; while(now!=s) { remain[last[now]]-=ans; remain[last[now]^1]+=ans; now=v[last[now]^1]; } return ans; } void bfs(int s,int t) { for (int i=s;i<=t;i++) deep[i]=t; deep[t]=0; queue<int> p; p.push(t); while (!p.empty()) { int now=p.front(); p.pop(); for (int i=point[now];i!=-1;i=next[i]) if (deep[v[i]]==t&&remain[i^1]) deep[v[i]]=deep[now]+1,p.push(v[i]); } } void isap(int s,int t) { maxflow=0; bfs(s,t); for (int i=s;i<=t;i++) cur[i]=point[i]; for (int i=s;i<=t;i++) num[deep[i]]++; int now=s; while (deep[s]<t) { if (now==t) { maxflow+=addflow(s,t); now=s; } int p=false; for (int i=cur[now];i!=-1;i=next[i]) if (deep[v[i]]+1==deep[now]&&remain[i]) { cur[now]=i; p=true; last[v[i]]=i; now=v[i]; break; } if (!p) { int minn=t-1; for (int i=point[now];i!=-1;i=next[i]) if (remain[i]) minn=min(minn,deep[v[i]]); if (!--num[deep[now]]) break; deep[now]=minn+1; num[deep[now]]++; cur[now]=point[now]; if (now!=s) now=v[last[now]^1]; } } } int main() { while (~scanf("%d",&n)) { scanf("%d%d%d%d%d%d",&a1,&a2,&an,&b1,&b2,&bn); a1++; a2++; b1++; b2++; for (int i=1;i<=n;i++) { char s[100]; scanf("%s",s); for (int j=0;j<n;j++) { if (s[j]=='X')a[i][j+1]=0; if (s[j]=='N')a[i][j+1]=inf; if (s[j]=='O')a[i][j+1]=2; } } clear(); build(); add(1,a1+1,2*an); add(a2+1,n+2,2*an); add(1,b1+1,2*bn); add(b2+1,n+2,2*bn); isap(1,n+2); //cout<<maxflow<<endl; if (maxflow<2*(an+bn)) { printf("No\n"); continue; } clear(); build(); add(1,a1+1,2*an); add(a2+1,n+2,2*an); add(1,b2+1,2*bn); add(b1+1,n+2,2*bn); isap(1,n+2); if (maxflow<2*(an+bn)) { printf("No\n"); continue; } else printf("Yes\n"); } }