日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

P4055-[JSOI2009]游戏【网络流,博弈】

發布時間:2023/12/3 javascript 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P4055-[JSOI2009]游戏【网络流,博弈】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P4055


題目大意

n?mn*mn?m的網格有的不能走,走過的不能走。開始有一個棋子先手可以決定位置,然后后先手輪流走,不能走的就輸了,求先手的必勝開始位置。


解題思路

我們將圖二分圖染色,然后可以走的兩兩連邊。如果這張圖有完全匹配,那么可以發現無論先手走到哪個點,后手可以順著完全匹配的邊走,因為這個邊一定是先手沒有走過的。

如果圖沒有完全匹配,考慮勝負情況。此時對于一個匹配來說,圖上會有一些點刪除后不會影響最大匹配,如果先手選擇了這些不需要的點作為起點,那么后手無論走到哪先手就可以順著最大匹配的方法走了。

現在問題是考慮如何求出所有最大匹配的不需要點,我們可以先跑一遍網絡流。然后從源點出發走沒有流完的邊,這些邊可以作為當前匹配沒有匹配的邊或者增廣路,然后走到的所有左邊的點就是答案。而匯點同理,走流完的邊即可,走到的右邊的點就是答案。


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define p(x,y) ((x)-1)*m+(y) using namespace std; const int N=110*110,inf=2147483647/3; const int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; struct node{int to,next,w; }a[N<<3]; int n,m,s,t,tot=1,ls[N],dep[N],col[N]; bool v[110][110],flag,ans[N];char st[110]; queue<int> q; void addl(int x,int y,int w){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;a[tot].w=0;return; } bool bfs(){while(!q.empty())q.pop();q.push(s);memset(dep,0,sizeof(dep));dep[s]=1;while(!q.empty()){int x=q.front();q.pop();for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(dep[y]||!a[i].w)continue;dep[y]=dep[x]+1;if(y==t)return 1;q.push(y);}}return 0; } int dinic(int x,int flow){int rest=0,k;if(x==t)return flow;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(dep[x]+1!=dep[y]||!a[i].w)continue;rest+=(k=dinic(y,min(a[i].w,flow-rest)));a[i].w-=k;a[i^1].w+=k;if(rest==flow)return flow;}if(!rest)dep[x]=0;return rest; } void dfs(int x,int c){if(dep[x])return;dep[x]=1;if(col[x]==c)ans[x]=flag=1;for(int i=ls[x];i;i=a[i].next)if(a[i].w==c)dfs(a[i].to,c);return; } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%s",st+1);for(int j=1;j<=m;j++)v[i][j]=(st[j]=='#');}s=0;t=p(n,m)+1;col[s]=col[t]=-1;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(!v[i][j]){if((i+j)&1)addl(p(i,j),t,1),col[p(i,j)]=0;else{addl(s,p(i,j),1),col[p(i,j)]=1;for(int k=0;k<4;k++){int x=i+dx[k],y=j+dy[k];if(x<1||y<1||x>n||y>m||v[x][y])continue;addl(p(i,j),p(x,y),1);}}}}while(bfs())dinic(s,inf);memset(dep,0,sizeof(dep)); dfs(s,1);dfs(t,0);if(!flag)return printf("LOSE")&0;printf("WIN\n");for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(ans[p(i,j)])printf("%d %d\n",i,j);return 0; }

總結

以上是生活随笔為你收集整理的P4055-[JSOI2009]游戏【网络流,博弈】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。