【2-SAT+二分】POJ 2749

来源:互联网 发布:红蜘蛛教学软件窗口化 编辑:程序博客网 时间:2024/05/17 04:28

http://hi.baidu.com/%8E%E1%D0%B3/blog/item/3f5354fa18498c01d9f9fd4a.html

#define N 1111vector<int> v[N];stack<int> s;bool vis[N];bool inStack[N];int low[N],dfn[N];int belong[N];//属于哪个强连通分量int n,m,step,t,A,B;int len;int sx[3],sy[3];int a[1001][2],b[1001][2];int d[N];int dis(int x1,int y1,int x2,int y2){    return abs(x1-x2)+abs(y1-y2);}void init(){    int i;    for(i=0;i<=2*n;i++){        v[i].clear();        vis[i] = 0;        inStack[i] = 0;    }    while(!s.empty())s.pop();}void add(int a,int b){    v[a].push_back(b);}//tarjan缩点void tarjan(int u){    vis[u]=true;    step++;    s.push(u);    inStack[u]=true;    low[u]=step,dfn[u]=step;    int i,j;    for(i=0;i<v[u].size();i++)    {        int x=v[u][i];        if(!vis[x])        {            tarjan(x);            low[u]=min(low[u],low[x]);        }        else        if(inStack[x])        low[u]=min(low[u],dfn[x]);    }    if(low[u]==dfn[u])    {        t++;        while(1)        {            int x=s.top();            s.pop();            belong[x]=t;            inStack[x]=false;            if(x==u)break;        }    }}void build(int mid){    int i,j;    init();    int u,v;    for(i=1;i<=A;i++){        u = a[i][0];        v = a[i][1];        add(u,v+n);        add(v,u+n);        add(u+n,v);        add(v+n,u);    }    for(i=1;i<=B;i++){        u = b[i][0];        v = b[i][1];        add(u,v);        add(v,u);        add(u+n,v+n);        add(v+n,u+n);    }    for(i=1;i<=n;i++){        for(j=i+1;j<=n;j++){            if(d[i]+d[j] > mid){                add(i,j+n);                add(j,i+n);            }            if(d[i+n]+d[j+n] > mid){                add(i+n,j);                add(j+n,i);            }            if(d[i]+d[j+n]+len > mid){                add(i,j);                add(j+n,i+n);            }            if(d[i+n]+d[j]+len > mid){                add(i+n,j+n);                add(j,i);            }        }    }}bool sat(int mid){    t = 0,step = 0;    build(mid);    int i;    for(i=1;i<=2*n;i++)        if(!vis[i])tarjan(i);    for(i=1;i<=n;i++)        if(belong[i] == belong[i+n])return false;    return true;}int main(){    while(scanf("%d%d%d",&n,&A,&B) != -1){        int i,j;        scanf("%d%d%d%d",&sx[1],&sy[1],&sx[2],&sy[2]);        len = dis(sx[1],sy[1],sx[2],sy[2]);        int l = 0,r = 0,mid;        for(i=1;i<=n;i++){            int x,y;            scanf("%d%d",&x,&y);            d[i] = dis(x,y,sx[1],sy[1]);            d[i+n] = dis(x,y,sx[2],sy[2]);            r = max(r,max(d[i],d[i+n]));        }        for(i=1;i<=A;i++){//hate            scanf("%d%d",&a[i][0],&a[i][1]);        }        for(i=1;i<=B;i++){//like            scanf("%d%d",&b[i][0],&b[i][1]);        }        int ans = -1;        r *= 3;        while(l<=r){            mid = (l+r)>>1;            if(sat(mid)){                ans = mid;                r = mid-1;            } else l = mid+1;        }        printf("%d\n",ans);    }    return 0;}







原创粉丝点击