题目描述
一个n×n栅格是由n行和n列顶点组成的一个无向图,如图所示。用(i,j)表示处于第i行第j列的顶点。除了边界顶点(即满足i=1,i=n,j=1或j=n的顶点(i,j)),栅格中的所有其他顶点都有四个相邻的顶点。
给定栅格中的m≤n2个起始点(x1,y1),…, (xm,ym),逃脱问题即确定从起始顶点到边界上的任何m个相异的顶点之间,是否存在m条顶点不相交的路径。例如,图中左边的栅格包含了一个逃脱,黑点表示起始点,一个逃脱路径由灰线表示;而右边的栅格则没有逃脱。
现给定一个栅格的n和m,以及其中m个起始点的坐标,你只需要判断是否存在逃脱即可。
输入输出格式
输入格式:
输入文件为escape.in
第一行是一个整数,为n (n≤35)。
第二行还是一个整数,为m。
以下m行,第(i+2)行包含两个整数xi和yi,表示第i行第j列的点是起始点。输入数据保证不会出现起始点坐标相同的情况。
输出格式:
输出文件为escape.out
只包括一行。若存在逃脱输出’YES’,不存在逃脱输出’NO’。
输入输出样例
输入样例#1:
6 10 2 2 2 4 2 6 3 1 3 2 3 4 3 6 4 2 4 4 4 6
输出样例#1:
YES
网络流
#include <cstdio> #include <queue> #define N 5000005 using namespace std; int dep[N],nextt[N<<1],to[N<<1],flow[N<<1],head[N],cnt=1,n,m,fx[5]={1,-1,0,0},fy[5]={0,0,-1,1}; inline void ins(int u,int v,int w) { nextt[++cnt]=head[u]; to[cnt]=v; flow[cnt]=w; head[u]=cnt; } bool bfs(int s,int t) { for(int i=s;i<=t;++i) dep[i]=-1; dep[s]=0; queue<int>q; q.push(s); for(int now;!q.empty();) { now=q.front();q.pop() ; for(int i=head[now];i;i=nextt[i]) { int v=to[i]; if(dep[v]==-1&&flow[i]) { dep[v]=dep[now]+1; if(v==t) return true; q.push(v); } } } return false; } inline int min(int a,int b){return a>b?b:a;} int dfs(int now,int t,int Limit) { if(now==t||!Limit) return Limit; int ret=0,f; for(int i=head[now];i;i=nextt[i]) { int v=to[i]; if(dep[v]==dep[now]+1&&flow[i]&&(f=dfs(v,t,min(Limit,flow[i])))) { flow[i]-=f; flow[i^1]+=f; ret+=f; Limit-=f; if(!Limit) break; } } if(ret!=Limit) dep[now]=-1; return ret; } int Dinic(int S,int T) { int ret=0; for(;bfs(S,T);ret+=dfs(S,T,0x3f3f3f3f)); return ret; } int main() { scanf("%d%d",&n,&m); int S=0,T=2*n*n+1; for(int x,y,i=1;i<=m;++i) { scanf("%d%d",&x,&y); ins(S,(x-1)*n+y,1); ins((x-1)*n+y,S,0); } for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) for(int k=0;k<4;++k) { int u=i+fx[k],v=j+fy[k]; if(u>0&&u<=n&&v>0&&v<=n) { ins((i-1)*n+j,(u-1)*n+v,1); ins((u-1)*n+v,(i-1)*n+j,0); } } for(int i=1;i<=n;++i) ins(i,T,1),ins(T,i,0); for(int i=n*n-n+1;i<=n*n;++i) ins(i,T,1),ins(T,i,0); for(int i=n+1;i<=n*n-n;i+=n) ins(i,T,1),ins(T,i,0); for(int i=1;i<=n;++i) ins(i*n,T,1),ins(T,i*n,0); int ans=Dinic(S,T); if(ans==m) printf("YES"); else printf("NO"); return 0; }
时间: 2024-11-02 06:48:12