2014-10-22 10:55:22
思路:POJ 2-SAT六题完结了。。这题依旧是二分答案,然后2-SAT判断,需要注意的是二分姿势以及每次二分都要重新建图。
1 /************************************************************************* 2 > File Name: 2749.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Tue 21 Oct 2014 08:34:43 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 1010; 27 28 int N,AA,BB; 29 int sx1,sy1,sx2,sy2,sd; 30 int first[maxn],next[maxn * maxn],ver[maxn * maxn],ecnt; 31 int low[maxn],dfn[maxn],sc[maxn],scnt,tot; 32 int x[maxn],y[maxn],A[maxn][2],B[maxn][2]; 33 int s1[maxn],s2[maxn]; 34 stack<int> S; 35 36 void Add_edge(int u,int v){ 37 next[++ecnt] = first[u]; 38 ver[ecnt] = v; 39 first[u] = ecnt; 40 } 41 42 void Build_graph(int val){ 43 memset(first,-1,sizeof(first)); 44 ecnt = 0; 45 for(int i = 0; i < AA; ++i){ 46 Add_edge(A[i][0] * 2,A[i][1] * 2 + 1); 47 Add_edge(A[i][0] * 2 + 1,A[i][1] * 2); 48 Add_edge(A[i][1] * 2,A[i][0] * 2 + 1); 49 Add_edge(A[i][1] * 2 + 1,A[i][0] * 2); 50 } 51 for(int i = 0; i < BB; ++i){ 52 Add_edge(B[i][0] * 2,B[i][1] * 2); 53 Add_edge(B[i][0] * 2 + 1,B[i][1] * 2 + 1); 54 Add_edge(B[i][1] * 2,B[i][0] * 2); 55 Add_edge(B[i][1] * 2 + 1,B[i][0] * 2 + 1); 56 } 57 for(int i = 0; i < N; ++i){ 58 for(int j = i + 1; j < N; ++j){ 59 if(s1[i] + s1[j] > val){ 60 Add_edge(i * 2,j * 2 + 1); 61 Add_edge(j * 2,i * 2 + 1); 62 } 63 if(s1[i] + s2[j] + sd > val){ 64 Add_edge(i * 2,j * 2); 65 Add_edge(j * 2 + 1,i * 2 + 1); 66 } 67 if(s2[i] + s1[j] + sd > val){ 68 Add_edge(i * 2 + 1,j * 2 + 1); 69 Add_edge(j * 2,i * 2); 70 } 71 if(s2[i] + s2[j] > val){ 72 Add_edge(i * 2 + 1,j * 2); 73 Add_edge(j * 2 + 1,i * 2); 74 } 75 } 76 } 77 } 78 79 void Dfs(int p){ 80 dfn[p] = low[p] = ++tot; 81 S.push(p); 82 for(int i = first[p]; i != -1; i = next[i]){ 83 int v = ver[i]; 84 if(!dfn[v]){ 85 Dfs(v); 86 low[p] = min(low[p],low[v]); 87 } 88 else if(!sc[v]){ 89 low[p] = min(low[p],dfn[v]); 90 } 91 } 92 if(low[p] == dfn[p]){ 93 ++scnt; 94 while(1){ 95 int x = S.top(); 96 S.pop(); 97 sc[x] = scnt; 98 if(x == p) break; 99 } 100 } 101 } 102 103 void Tarjan(){ 104 memset(low,0,sizeof(low)); 105 memset(dfn,0,sizeof(dfn)); 106 memset(sc,0,sizeof(sc)); 107 scnt = tot = 0; 108 while(!S.empty()) S.pop(); 109 for(int i = 0; i < 2 * N; ++i) 110 if(!dfn[i]) Dfs(i); 111 } 112 113 bool Solve(int val){ 114 Build_graph(val); 115 Tarjan(); 116 //check 117 for(int i = 0; i < 2 * N; i += 2){ 118 if(sc[i] == sc[i + 1]) 119 return false; 120 } 121 return true; 122 } 123 124 int main(){ 125 int tmax = -1; 126 scanf("%d%d%d",&N,&AA,&BB); 127 scanf("%d%d%d%d",&sx1,&sy1,&sx2,&sy2); 128 sd = abs(sx1 - sx2) + abs(sy1 - sy2); 129 for(int i = 0; i < N; ++i){ 130 scanf("%d%d",x + i,y + i); 131 s1[i] = abs(sx1 - x[i]) + abs(sy1 - y[i]); 132 s2[i] = abs(sx2 - x[i]) + abs(sy2 - y[i]); 133 tmax = max(tmax,max(s1[i],s2[i])); 134 } 135 for(int i = 0; i < AA; ++i){ 136 scanf("%d%d",&A[i][0],&A[i][1]); 137 --A[i][0]; 138 --A[i][1]; 139 } 140 for(int i = 0; i < BB; ++i){ 141 scanf("%d%d",&B[i][0],&B[i][1]); 142 --B[i][0]; 143 --B[i][1]; 144 } 145 int ans = -1,mid,l = 0,r = 2 * tmax + sd + 1; 146 while(l < r){ 147 mid = getmid(l,r); 148 if(Solve(mid)){ 149 ans = mid; 150 r = mid; 151 } 152 else l = mid + 1; 153 } 154 printf("%d\n",ans); 155 return 0; 156 } 157