Hdu--3622(2-SAT,scc缩点)
2014-10-16 22:56:40
思路:一道比较明显的2-SAT(好吧,做到现在2-SAT的题目都挺明显的QAQ),答案不大,直接二分答案来做,要注意的建图过程。
核心是找必须条件,如果 distance(i,j) < 2 * r,那么说明 i,j 点间的边不能连(一连就会有重叠面积),所以必须条件是:如果到 i 那么必须连 j^1,如果到 j 那么必须连 i^1。
1 /************************************************************************* 2 > File Name: 3622.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Thu 16 Oct 2014 09:20:58 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 double eps = 1e-6; 27 28 int N,cnt; 29 double x[205],y[205]; 30 double g[205][205]; 31 int low[205],dfn[205],sc[205],scnt,tot; 32 vector<double> G[205]; 33 stack<int> S; 34 double dmax; 35 36 double Dis(int a,int b){ 37 return sqrt((x[b] - x[a]) * (x[b] - x[a]) + 38 (y[b] - y[a]) * (y[b] - y[a])); 39 } 40 41 void Cal_dis(){ 42 int top = 2 * N; 43 for(int i = 0; i < top; ++i) 44 for(int j = 0; j < top; ++j){ 45 g[i][j] = g[j][i] = Dis(i,j); 46 dmax = g[i][j] > dmax ? g[i][j] : dmax; 47 } 48 } 49 50 void Dfs(int p){ 51 dfn[p] = low[p] = ++tot; 52 S.push(p); 53 int top = G[p].size(); 54 for(int i = 0; i < top; ++i){ 55 int v = G[p][i]; 56 if(!dfn[v]){ 57 Dfs(v); 58 low[p] = min(low[p],low[v]); 59 } 60 else if(!sc[v]){ 61 low[p] = min(low[p],dfn[v]); 62 } 63 } 64 if(low[p] == dfn[p]){ 65 ++scnt; 66 while(1){ 67 int x = S.top(); 68 S.pop(); 69 sc[x] = scnt; 70 if(x == p) break; 71 } 72 } 73 } 74 75 void Tarjan(){ 76 memset(low,0,sizeof(low)); 77 memset(dfn,0,sizeof(dfn)); 78 memset(sc,0,sizeof(sc)); 79 while(!S.empty()) S.pop(); 80 scnt = tot = 0; 81 int top = 2 * N; 82 for(int i = 0; i < top; ++i) 83 if(!dfn[i]) Dfs(i); 84 } 85 86 bool Solve(double d){ 87 //Build graph 88 int top = 2 * N; 89 for(int i = 0; i < top; ++i) 90 G[i].clear(); 91 for(int i = 0; i < top; ++i){ 92 int j; 93 if(i % 2) j = i + 1; 94 else j = i + 2; 95 for(; j < top; ++j){ 96 if(g[i][j] < 2 * d){ 97 G[i].push_back(j ^ 1); 98 G[j].push_back(i ^ 1); 99 } 100 } 101 } 102 //Judge 103 Tarjan(); 104 for(int i = 0; i < N; ++i) 105 if(sc[i * 2] == sc[i * 2 + 1]) return false; 106 return true; 107 } 108 109 int main(){ 110 int x1,y1,x2,y2; 111 while(scanf("%d",&N) != EOF){ 112 for(int i = 0; i < N; ++i){ 113 scanf("%lf%lf%lf%lf",&x[i * 2],&y[i * 2], 114 &x[i * 2 + 1],&y[i * 2 + 1]); 115 } 116 dmax = 0.0; 117 Cal_dis(); 118 int top = 2 * N; 119 double ans,mid,L = 0,R = dmax; 120 while(fabs(R - L) >= eps){ 121 mid = L + (R - L) / 2.0; 122 if(Solve(mid)) 123 L = mid; 124 else 125 R = mid; 126 } 127 printf("%.2f\n",L); 128 } 129 return 0; 130 }

浙公网安备 33010602011771号