P1971 [NOI2011]兔兔与蛋蛋游戏

传送门

思路比较迷……题解在这里

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
int read(){
    R int res,f=1;R char ch;
    while((ch=getchar())>'9'||ch<'0')(ch=='-')&&(f=-1);
    for(res=ch-'0';(ch=getchar())>='0'&&ch<='9';res=res*10+ch-'0');
    return res*f;
}
const int N=105,M=10005;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
struct eg{int v,nx;}e[M];int head[M],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int id[N][N],vis[M],st[M],match[M];bool ban[M],win[M],mp[N][N];
int n,m,tim,top,cnt,q,bx,by;char s[N];
bool find(int u){
	if(ban[u])return 0;go(u){
		if(vis[v]==tim||ban[v])continue;
		vis[v]=tim;if(!match[v]||find(match[v])){
			match[u]=v,match[v]=u;return 1;
		}
	}return 0;
}
int main(){
//	freopen("testdata.in","r",stdin);
	n=read(),m=read();
	fp(i,1,n){
		scanf("%s",s+1);
		fp(j,1,m)switch(s[j]){
			case 'X':mp[i][j]=1;break;
			case 'O':mp[i][j]=0;break;
			case '.':mp[i][j]=1,bx=i,by=j;break;
		}
	}fp(i,1,n)fp(j,1,m)id[i][j]=++cnt;
	fp(i,1,n)fp(j,1,m)if(mp[i][j])fp(k,0,3){
		int x=i+dx[k],y=j+dy[k];
		if(x>=1&&x<=n&&y>=1&&y<=m&&!mp[x][y])add(id[i][j],id[x][y]),add(id[x][y],id[i][j]);
	}fp(i,1,n)fp(j,1,m)if(mp[i][j])++tim,find(id[i][j]);
	q=read();fp(i,1,(q<<1)){
		int x=id[bx][by];ban[x]=1;
		if(match[x]){
			int y=match[x];match[x]=match[y]=0;
			++tim,win[i]=!find(y);
		}bx=read(),by=read();
	}
	fp(i,1,q)if(win[(i<<1)-1]&&(win[i<<1]))st[++top]=i;
	printf("%d
",top);fp(i,1,top)printf("%d
",st[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/bztMinamoto/p/10139933.html