POJ Building roads [二分答案 2SAT]

睡觉啦

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1005,M=2e6+5,INF=1e7;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,A,B,x,y;
struct point{int x,y;}a[N],s1,s2,f[N<<1];
inline int dis(point &a,point &b){return abs(a.x-b.x)+abs(a.y-b.y);}
struct edge{
    int v,ne;
}e[M];
int cnt,h[N];
inline void ins(int u,int v){//if(u==1 || v==1) printf("ins %d %d\n",u,v);
    cnt++;
    e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
void build(int mid){
    cnt=0; memset(h,0,sizeof(h));
    for(int i=1;i<=A;i++) 
        ins(f[i].x,f[i].y+n),ins(f[i].x+n,f[i].y),ins(f[i].y,f[i].x+n),ins(f[i].y+n,f[i].x);
    for(int i=A+1;i<=A+B;i++)
        ins(f[i].x,f[i].y),ins(f[i].x+n,f[i].y+n),ins(f[i].y,f[i].x),ins(f[i].y+n,f[i].x+n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) if(i!=j){
            if(dis(a[i],s1)+dis(a[j],s1)>mid) ins(i,j+n),ins(j,i+n);
            if(dis(a[i],s2)+dis(a[j],s2)>mid) ins(i+n,j),ins(j+n,i);
            if(dis(a[i],s1)+dis(s1,s2)+dis(s2,a[j])>mid) ins(i,j),ins(j+n,i+n);
            if(dis(a[i],s2)+dis(s1,s2)+dis(s1,a[j])>mid) ins(i+n,j+n),ins(j,i);
        }
}
int dfn[N],dfc,low[N],belong[N],scc;
int st[N],top;
void dfs(int u){//printf("Dfs %d\n",u);
    dfn[u]=low[u]=++dfc;
    st[++top]=u;
    for(int i=h[u];i;i=e[i].ne){
        int v=e[i].v;
        if(!dfn[v]) dfs(v),low[u]=min(low[u],low[v]);
        else if(!belong[v]) low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scc++; int x=0;
        while(x!=u){
            x=st[top--];
            belong[x]=scc;
        }
    }
}
bool check(int mid){//printf("check %d\n",mid);
    build(mid);
    for(int i=1;i<=n+n;i++) dfn[i]=low[i]=belong[i]=0;
    dfc=scc=top=0;
    for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
    for(int i=1;i<=n;i++) if(belong[i]==belong[i+n]) return false;
    return true;
}

int l=0,r=INF;
void solve(){
    int ans=-1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
}
int main(){
    freopen("in","r",stdin);
    n=read();A=read();B=read();
    s1.x=read();s1.y=read();s2.x=read();s2.y=read();
    for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
    for(int i=1;i<=A;i++) f[i].x=read(),f[i].y=read();
    for(int i=A+1;i<=A+B;i++) f[i].x=read(),f[i].y=read(),l=max( l,dis(a[ f[i].x ],a[ f[i].y ]) );
    solve();
}

 

posted @ 2017-03-13 23:42  Candy?  阅读(183)  评论(0编辑  收藏  举报