http://poj.org/problem?id=2749
2-sat + 二分
在二分里面根据情况 有时候是求大的 有时候是求小的
这个二分里面 我分的时候
while(l<r)
l=mid+1;
r=mid;
因为 mid可能就是答案 还有就是如果最后停在 r为有边界时 r可能不是答案需要特判 一下
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#define LL long long
using namespace std;
const int N=1005;
int head[N],I;
struct ss
{
int j,next;
}side[N*N];
struct key
{
int i,j;
}hate[N],fri[N];
int Adist[N],Bdist[N];
int low[N],dfn[N],f[N],deep;
bool in[N],visited[N];
stack<int>st;
int ans[N*N];
int n,m1,m2;
void build(int x,int y)
{
side[I].j=y;
side[I].next=head[x];
head[x]=I++;
}
void Tarjan(int x)
{
visited[x]=true;
in[x]=true;
st.push(x);
low[x]=dfn[x]=deep++;
for(int t=head[x];t!=-1;t=side[t].next)
{
int k=side[t].j;
if(visited[k]==false)
{
Tarjan(k);
low[x]=min(low[x],low[k]);
}else if(in[k]==true)
{
low[x]=min(low[x],dfn[k]);
}
}
if(low[x]==dfn[x])
{
int k;
do
{
k=st.top();
st.pop();
in[k]=false;
f[k]=x;
}while(k!=x);
}
}
bool solve(int d,int s)
{
memset(head,-1,sizeof(head));
I=0;
for(int i=1;i<=n;++i)
{
for(int j=1;j<i;++j)
{
int w=0;
if(Adist[i]+Adist[j]>d)
{build(i,j+n);build(j,i+n);++w;}
if(Bdist[i]+Bdist[j]>d)
{build(i+n,j);build(j+n,i);++w;}
if(Adist[i]+Bdist[j]+s>d)
{build(i,j);build(j+n,i+n);++w;}
if(Bdist[i]+Adist[j]+s>d)
{build(i+n,j+n);build(j,i);++w;}
if(w==4)
return false;
}
}
for(int l=1;l<=m1;++l)
{
build(hate[l].i,hate[l].j+n);build(hate[l].j,hate[l].i+n);
build(hate[l].i+n,hate[l].j);build(hate[l].j+n,hate[l].i);
}
for(int l=1;l<=m2;++l)
{
build(fri[l].i,fri[l].j);build(fri[l].j,fri[l].i);
build(fri[l].i+n,fri[l].j+n);build(fri[l].j+n,fri[l].i+n);
}
memset(visited,false,sizeof(visited));
memset(in,false,sizeof(in));
memset(f,-1,sizeof(f));
while(!st.empty())
st.pop();
deep=0;
int l;
for(l=1;l<n;++l)
{
if(!visited[l])
Tarjan(l);
if(f[l]!=-1&&f[l]==f[l+n])
break;
}
if(l<n)
return false;
else
return true;
}
int main()
{
//freopen("data.txt","r",stdin);
while(scanf("%d %d %d",&n,&m1,&m2)!=EOF)
{
int sx1,sy1,sx2,sy2;
scanf("%d %d %d %d",&sx1,&sy1,&sx2,&sy2);
int s=abs(sx1-sx2)+abs(sy1-sy2);
for(int i=1;i<=n;++i)
{
int x,y;
scanf("%d %d",&x,&y);
Adist[i]=abs(x-sx1)+abs(y-sy1);
Bdist[i]=abs(x-sx2)+abs(y-sy2);
}
int L=0;
for(int i=1;i<=n;++i)
{
for(int j=1;j<i;++j)
{
ans[++L]=Adist[i]+Adist[j];
ans[++L]=Bdist[i]+Bdist[j];
ans[++L]=Adist[i]+Bdist[j]+s;
ans[++L]=Bdist[i]+Adist[j]+s;
}
}
for(int i=1;i<=m1;++i)
scanf("%d %d",&hate[i].i,&hate[i].j);
for(int i=1;i<=m2;++i)
scanf("%d %d",&fri[i].i,&fri[i].j);
sort(ans+1,ans+L+1);
int l=1,r=L;
while(l<r)
{//cout<<l<<" "<<r<<endl;
int mid=(l+r)/2;
if(solve(ans[mid],s))
r=mid;
else
l=mid+1;
}
if(!solve(ans[r],s))
printf("-1\n");
else
printf("%d\n",ans[r]);
}
return 0;
}
浙公网安备 33010602011771号