1. 程式人生 > >洛谷 P2691 逃離

洛谷 P2691 逃離

() scanf fine too style 如圖所示 cape -m esp

題目描述

一個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; }

洛谷 P2691 逃離