您的位置:首页 > 其它

NOI2011 兔兔与蛋蛋游戏

2015-08-04 21:24 387 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=2437

这道题真是极好的。

75分做法:

搜索。

出题人真的挺良心的,前15个数据点的范围都很小,可以直接搜索。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj

using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define re(i,a,b)  for(i=a;i<=b;i++)
#define red(i,a,b) for(i=a;i>=b;i--)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))

template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

const DB EPS=1e-9;
inline int sgn(DB x){if(abs(x)<EPS)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

inline int gint()
{
int res=0;bool neg=0;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return 0;
if(z=='-'){neg=1;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
return (neg)?-res:res;
}
inline LL gll()
{
LL res=0;bool neg=0;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return 0;
if(z=='-'){neg=1;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
return (neg)?-res:res;
}

const int maxN=40;
const int dx[]={0,0,-1,1};
const int dy[]={1,-1,0,0};
const int maxcnt=maxN*maxN;
const int maxK=1000;

int N,M,K;
char mp[maxN+10][maxN+10];
int idx[maxN+10][maxN+10],cntB,cntW;
int x,y;

int now,first[maxcnt+100];
struct Tedge{int v,next;}edge[maxcnt*4+100];
inline void addedge(int u,int v){now++;edge[now].v=v;edge[now].next=first[u];first[u]=now;}

int maxmatching;
int form[maxcnt+100],flag[maxcnt+100];

int vis[maxcnt+100];
inline int find(int u)
{
int i,v;
vis[u]=1;
for(i=first[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)
if(flag[v]==0 && (form[v]==0 || (vis[form[v]]==0 && find(form[v]))))
{
form[u]=v;form[v]=u;
return 1;
}
return 0;
}
inline int check(int u)
{
int i;
re(i,1,cntB+cntW)vis[i]=0;
return find(u);
}

inline void disuse(int u)
{
if(form[u]==0)return;
int v=form[u];
form[u]=form[v]=0;
maxmatching--;
flag[u]=1;
if(check(v))maxmatching++;
}
inline void use(int u)
{
flag[u]=0;
if(check(u))maxmatching++;
}

inline void cover(int u,int v)
{
if(form[u]==v){flag[u]=flag[v]=1;return;}
int f=0,g=0;
if(form[u]!=0)g=form[u],form[g]=form[u]=0,maxmatching--;
if(form[v]!=0)f=form[v],form[f]=form[v]=0,maxmatching--;
form[u]=v;form[v]=u;
flag[u]=flag[v]=1;
maxmatching++;
if(f && check(f))maxmatching++;
if(g && check(g))maxmatching++;
}

int tot,out[maxK+100];

int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
int i,j,k;
N=gint();M=gint();
re(i,1,N)scanf("%s\n",mp[i]+1);
re(i,1,N)re(j,1,M)
{
if(mp[i][j]=='O')idx[i][j]=++cntW;else idx[i][j]=++cntB;
if(mp[i][j]=='.')mp[i][j]='X',x=i,y=j;
}
re(i,1,N)re(j,1,M)if(mp[i][j]=='O')idx[i][j]+=cntB;
now=-1;mmst(first,-1);
re(i,1,N)re(j,1,M)if(mp[i][j]=='X')re(k,0,3)
{
int x=i+dx[k],y=j+dy[k];
if(x<1 || N<x || y<1 || M<y) continue;
if(mp[x][y]=='O')addedge(idx[i][j],idx[x][y]),addedge(idx[x][y],idx[i][j]);
}

re(i,1,cntB)if(check(i))maxmatching++;

K=gint();
re(i,1,K)
{
int tx=gint(),ty=gint(),u=idx[x][y],v=idx[tx][ty];
disuse(u);
int res1=maxmatching;
use(u);
int res2=maxmatching;
cover(u,v);
if(res1!=res2)
{
int f=0,t;
for(j=first[v],t=edge[j].v;j!=-1;j=edge[j].next,t=edge[j].v)
if(flag[t]==0 && form[t]==0){f=1;break;}
if(!f)
{
int res3=maxmatching;
for(j=first[v],t=edge[j].v;j!=-1;j=edge[j].next,t=edge[j].v)if(flag[t]==0)
{
disuse(t);
int res4=maxmatching;
use(t);
if(res4==res3){f=1;break;}
}
}
if(f)out[++tot]=i;
}
x=gint();y=gint();
}
PF("%d\n",tot);
re(i,1,tot)PF("%d\n",out[i]);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: