祝各位圣诞后快乐(逃)
题目传送门
分析:
首先棋盘上的路径构成的图是一张二分图
那么对于一个二分图,先求出最大匹配,先手如果走到关键匹配点,只要后手顺着匹配边走,由于不再会出现增广路径,所以走到最后先手就必败
所以Alice只要到非关键匹配点,Bob便一定会走到关键匹配点,然后Alice便必胜
于是求一下那些点是非关键匹配点就好了
真难想233
我好菜233
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<map> #include<queue> #define maxn 500005 #define maxm 105 #define INF 0x3f3f3f3f using namespace std; inline long long getint() { long long num=0,flag=1;char c; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1; while(c>='0'&&c<='9')num=num*10+c-48,c=getchar(); return num*flag; } int n,m; int S,T; int fir[maxn],nxt[maxn],to[maxn],cap[maxn],cnt; int h[maxn],vis[maxn]; char s[maxm][maxm]; int ans[maxm][maxm]; inline void newnode(int u,int v,int w) {to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,cap[cnt]=w;} inline void insert(int u,int v,int w) {newnode(u,v,w),newnode(v,u,0);} inline bool bfs() { memset(h,-1,sizeof h);h[S]=0; queue<int>Q;Q.push(S); while(!Q.empty()) { int u=Q.front();Q.pop(); for(int i=fir[u];i;i=nxt[i]) if(!~h[to[i]]&&cap[i])h[to[i]]=h[u]+1,Q.push(to[i]); } return ~h[T]; } inline int aug(int u,int flow) { if(u==T||!flow)return flow; int used=0; for(int i=fir[u];i;i=nxt[i]) if(cap[i]&&h[to[i]]==h[u]+1) { int delta=aug(to[i],min(flow-used,cap[i])); cap[i]-=delta,cap[i^1]+=delta,used+=delta; if(used==flow)return flow; } if(!used)h[u]=-1; return used; } inline int dinic() { int num=0; while(bfs())num+=aug(S,INF); return num; } inline void dfs(int u) { vis[u]=1; for(int i=fir[u];i;i=nxt[i])if(!vis[to[i]]&&cap[i])dfs(to[i]); } inline void dfs2(int u) { vis[u]=1; for(int i=fir[u];i;i=nxt[i])if(!vis[to[i]]&&cap[i^1])dfs2(to[i]); } inline int getid(int i,int j){return i*m+j-m;} int main() { n=getint(),m=getint();int num=0; for(int i=1;i<=n;i++)scanf("%s",s[i]+1); S=n*m+1,T=S+1;cnt=1; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) { if(((i+j)&1)&&s[i][j]=='.') { insert(S,getid(i,j),1); if(s[i-1][j]=='.')insert(getid(i,j),getid(i-1,j),INF); if(s[i+1][j]=='.')insert(getid(i,j),getid(i+1,j),INF); if(s[i][j-1]=='.')insert(getid(i,j),getid(i,j-1),INF); if(s[i][j+1]=='.')insert(getid(i,j),getid(i,j+1),INF); } if(!((i+j)&1)&&s[i][j]=='.')insert(getid(i,j),T,1); } dinic(); dfs(S); for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) if(((i+j)&1)&&s[i][j]=='.'&&vis[getid(i,j)])ans[i][j]=1,num++; memset(vis,0,sizeof vis); dfs2(T); for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) if(!((i+j)&1)&&s[i][j]=='.'&&vis[getid(i,j)])ans[i][j]=1,num++; printf("%d ",num); for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) if(ans[i][j])printf("%d %d ",i,j); }