poj2749

题解:

二分答案

先按照原有的条件建边,然后按照二分不能满足的条件建边

然后判断是否可行

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
const int N=2005;
using namespace std;
int n,m1,m2,num,flag,ans,tot,head[N],X[N],Y[N],dist1[N],dist2[N];
int scc[N],vis[N],stack1[N],x1,x2,x,y,y11,y2,stack2[N];
struct edge{int v,next;}g[N*N];
void init()  
{  
    memset(head,0,sizeof(head));  
    memset(vis,0,sizeof(vis));  
    memset(scc,0,sizeof(scc));  
    stack1[0]=stack2[0]=num=0;  
    flag=1;  
}  
void jb(int u,int v)  
{  
    num++;  
    g[num].v=v;  
    g[num].next=head[u];  
    head[u]=num;  
}  
int js(int x1,int y1,int x2,int y2){return abs(x1-x2)+abs(y1-y2);}  
void dfs(int cur,int &sig,int &cnt)  
{  
    if (!flag)return;  
    vis[cur]=++sig;  
    stack1[++stack1[0]]=cur;  
    stack2[++stack2[0]]=cur;  
    for (int i=head[cur];i;i=g[i].next)  
     if (!vis[g[i].v]) dfs(g[i].v,sig,cnt);  
     else if (!scc[g[i].v])  
      while (vis[stack2[stack2[0]]]>vis[g[i].v])stack2[0]--;  
    if (stack2[stack2[0]]==cur)  
     {  
        stack2[0]--;  
        ++cnt;  
        do  
         {  
            scc[stack1[stack1[0]]]=cnt;  
            int tmp=stack1[stack1[0]];  
            if ((tmp>=n&&scc[tmp-n]==cnt)||(tmp<n&&scc[tmp+n]==cnt))  
             {  
                flag=0;  
                return;  
             }  
         }  
        while (stack1[stack1[0]--]!=cur);  
     }  
}  
void solve()  
{  
    int l=0,r=4000000;  
    ans=-1;  
    while (l<=r)  
     {  
        int mid=(l+r)/2;  
        init();  
        num=0;  
        for (int i=1;i<=m1;i++)  
         {  
            int u=X[i],v=Y[i];  
            jb(u,v+n);jb(u+n,v);  
            jb(v,u+n);jb(v+n,u);  
         }  
        for (int i=m1+1;i<=m1+m2;i++)  
         {  
            int u=X[i],v=Y[i];  
            jb(u,v);jb(v,u);  
            jb(u+n,v+n);jb(v+n,u+n);  
         }  
        for (int i=0;i<n;i++)  
         for (int j=0;j<n;j++)  
          {  
            if (i==j)continue;  
            if (dist1[i]+dist1[j]>mid)jb(i,j+n);  
            if (dist2[i]+dist2[j]>mid)jb(i+n,j);  
            if (dist1[i]+dist2[j]+tot>mid)jb(i,j);  
            if (dist2[i]+dist1[j]+tot>mid)jb(i+n,j+n);  
          }  
        int sig=0,cnt=0;  
        for (int i=0;i<n+n&&flag;i++)  
          if (!vis[i])dfs(i,sig,cnt);   
        if (flag)  
         {  
            ans=mid;  
            r=mid-1;  
         }  
        else l=mid+1;  
     }  
}  
int main()  
{  
    while (~scanf("%d%d%d",&n,&m1,&m2))  
     {  
        scanf("%d%d%d%d",&x1,&y11,&x2,&y2);  
        tot=js(x1,y11,x2,y2);  
        for (int i=0;i<n;i++)  
         {  
            scanf("%d%d",&x,&y);  
            dist1[i]=js(x,y,x1,y11);  
            dist2[i]=js(x,y,x2,y2);  
         }  
        for (int i=1;i<=m1+m2;i++)  
         {  
            scanf("%d%d",&X[i],&Y[i]);  
            X[i]--;Y[i]--;  
         }  
        solve();  
        printf("%d
",ans);  
     }  
    return 0;  
}  
原文地址:https://www.cnblogs.com/xuanyiming/p/8119609.html