POJ 2749 Building roads 2-sat+二分答案

把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性

所以可以二分最大距离,加边+check

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<vector>
  5 #include<stack>
  6 #define N 5010
  7 #define INF 4000000
  8 using namespace std;
  9 int dis1[N],a,b,n,dis2[N],sx1,sy1,sx2,sy2,head[N],dfn[N],low[N],ecnt,x[N],y[N],tmp,ok,belong[N],hate[N][3],love[N][3],indx,inst[N],cnt;
 10 stack <int> st;
 11 int read()
 12 {
 13     int ret=0,neg=1;
 14     char j=getchar();
 15     for (;j>'9' || j<'0';j=getchar())
 16     if (j=='-') neg=-1;
 17     for (;j>='0' && j<='9';j=getchar())
 18     ret=ret*10+j-'0';
 19     return ret*neg;
 20 }
 21 struct edge
 22 {
 23     int nxt,v;
 24 }e[N*N];
 25 int ABS(int x)
 26 {
 27     return x>0?x:-x;
 28 }
 29 void add(int u,int v)
 30 {
 31     e[++ecnt].v=v;
 32     e[ecnt].nxt=head[u];
 33     head[u]=ecnt;
 34 }
 35 void init()
 36 {
 37     memset(head,0,sizeof(head));
 38     memset(dfn,0,sizeof(dfn));
 39     ecnt=0;
 40     indx=0;
 41     cnt=0;
 42 }
 43 void buildG(int lim)
 44 {
 45     for (int i=1;i<=a;i++)
 46     {
 47     int u=hate[i][0],v=hate[i][1];
 48     add(u,v+n),add(v,u+n),add(u+n,v),add(v+n,u);
 49     }
 50     for (int i=1;i<=b;i++)
 51     {
 52     int u=love[i][0],v=love[i][1];
 53     add(u,v),add(v+n,u+n),add(u+n,v+n),add(v,u);
 54     }
 55     for (int i=1;i<=n;i++)
 56     for (int j=i+1;j<=n;j++)
 57     {
 58         if (dis1[i]+dis2[j]+tmp>lim)
 59         add(i,j),add(j+n,i+n);
 60         if (dis2[i]+dis1[j]+tmp>lim)
 61         add(i+n,j+n),add(j,i);
 62         if (dis1[i]+dis1[j]>lim)
 63         add(i,j+n),add(j,i+n);
 64         if (dis2[i]+dis2[j]>lim)
 65         add(i+n,j),add(j+n,i);
 66     }
 67 }
 68 void tar(int u)
 69 {
 70     dfn[u]=low[u]=++indx;
 71     inst[u]=1;
 72     st.push(u);
 73     for (int i=head[u];i;i=e[i].nxt)
 74     {
 75     int v=e[i].v;
 76     if (!dfn[v])
 77     {
 78         tar(v);
 79         low[u]=min(low[v],low[u]);
 80     }
 81     else if (inst[v])
 82         low[u]=min(dfn[v],low[u]);
 83     }
 84     if (low[u]==dfn[u])
 85     {
 86     int t;
 87     ++cnt;
 88     while (1)
 89     {
 90         t=st.top();
 91         inst[t]=0;
 92         st.pop();
 93         belong[t]=cnt;
 94         if (t==u) break;
 95     }
 96     }
 97 }
 98 int check(int lim)
 99 {
100     init();
101     buildG(lim);
102     for (int i=1;i<=2*n;i++)
103     if (!dfn[i]) tar(i);
104     for (int i=1;i<=n;i++)
105     if (belong[i]==belong[i+n]) return 0;
106     return 1;
107 }
108 int main()
109 {
110     n=read(),a=read(),b=read();
111     sx1=read(),sy1=read(),sx2=read(),sy2=read();
112     tmp=ABS(sx1-sx2)+ABS(sy1-sy2);
113     for (int i=1;i<=n;i++)
114     {
115     x[i]=read(),y[i]=read();
116     dis1[i]=ABS(x[i]-sx1)+ABS(y[i]-sy1);
117     dis2[i]=ABS(x[i]-sx2)+ABS(y[i]-sy2);
118     }
119     for (int i=1;i<=a;i++)
120     hate[i][0]=read(),hate[i][1]=read();
121     for (int i=1;i<=b;i++)
122     love[i][0]=read(),love[i][1]=read();
123     int l=0,r=INF,mid;
124     while (l<r)
125     {
126     mid=(l+r)>>1;
127     if (check(mid)==1) r=mid;
128     else l=mid+1;
129     }
130     printf("%d\n",l==INF?-1:l);
131     return 0;
132 }

 

posted @ 2017-11-18 09:32  MSPqwq  阅读(121)  评论(0编辑  收藏  举报