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 }