洛谷 P2691 逃離
阿新 • • 發佈:2017-09-27
() scanf fine too style 如圖所示 cape -m esp
輸出樣例#1:
題目描述
一個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
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 逃離