您的位置:首页 > 其它

poj 2723 Get Luffy Out 2sat

2013-05-21 22:46 225 查看
二分+2sat判可行性
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1024*2+9;
int doorx[1<<12],doory[1<<12],x[maxn],y[maxn];
int n,m;
int dfn[maxn<<1],low[maxn<<1],stack[maxn<<1],instack[maxn<<1],s[maxn<<1];
int count,top,con;
int head[maxn<<1],lon;
struct
{
int next,to;
}e[1000000];
void edgemake(int from,int to)
{
e[++lon].to=to;
e[lon].next=head[from];
head[from]=lon;
}
void edgeini()
{
memset(head,-1,sizeof(head));
lon=-1;
}
void tarjan(int t)
{
dfn[t]=low[t]=++count;
stack[++top]=t;
instack[t]=1;
for(int k=head[t];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(dfn[u]==-1)
{
tarjan(u);
low[t]=min(low[t],low[u]);
}
else if(instack[u]==1)
low[t]=min(low[t],dfn[u]);
}
if(dfn[t]==low[t])
{
++con;
while(1)
{
int u=stack[top--];
instack[u]=0;
s[u]=con;
if(u==t) break;
}
}
}
void tarjan()
{
memset(dfn,-1,sizeof(dfn));
memset(instack,0,sizeof(instack));
count=top=con=0;
for(int i=0;i<=n*2*2-1;i++)
if(dfn[i]==-1)
tarjan(i);
}

bool check()
{
for(int i=0;i<=n*4-1-1;i+=2)
if(s[i]==s[i+1])
return false;
return true;
}

bool check(int ret)
{
edgeini();
for(int i=1;i<=n;i++)
{
edgemake(x[i]*2,y[i]*2+1);
edgemake(y[i]*2,x[i]*2+1);
}
for(int i=1;i<=ret;i++)
{
edgemake(2*doorx[i]+1,2*doory[i]);
edgemake(2*doory[i]+1,2*doorx[i]);
}
tarjan();

return check();
}

int main()
{
while(scanf("%d %d",&n,&m),n||m)
{
edgeini();
for(int i=1,tmp;i<=n;i++)
{
scanf("%d %d",&x[i],&y[i]);
}
for(int i=1;i<=m;i++)
scanf("%d %d",&doorx[i],&doory[i]);
int st=0,ed=m;
while(st<ed)
{
int mid=(st+ed+1)>>1;
if(check(mid))
st=mid;
else
ed=mid-1;
}
printf("%d\n",st);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: