打个手熟
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #define N 105*2 #define M 40000+5 #define ll double #define eps 1e-5 using namespace std; inline ll Max(ll a,ll b){return a>b?a:b;} inline ll Min(ll a,ll b){return a<b?a:b;} struct Point{ double x,y; }p[N]; inline double dist(Point a,Point b){return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));} struct Edge{ int to, nex; }edge1[M],edge2[M]; int head1[N],head2[N], edgenum1, edgenum2; void addedge(int u, int v){ edge1[edgenum1]. to = v; edge1[edgenum1]. nex = head1[u]; head1[u] = edgenum1 ++; edge2[edgenum2]. to = u; edge2[edgenum2]. nex = head2[v]; head2[v] = edgenum2 ++; } bool vis1[N], vis2[N]; int belong[N], T[N]; int Bcnt, Tcnt; void dfs1(int x){ vis1[x] = true; for(int i = head1[x]; i!=-1; i = edge1[i].nex) if(!vis1[edge1[i].to]) dfs1(edge1[i].to); T[Tcnt++] = x; } void dfs2(int x){ vis2[x] = true; belong[x] = Bcnt; for(int i = head2[x]; i!=-1; i = edge2[i].nex) if(!vis2[edge2[i].to]) dfs2(edge2[i].to); } void init(){ memset(head1, -1, sizeof(head1)); memset(head2, -1, sizeof(head2)); memset(vis1, 0, sizeof(vis1)); memset(vis2, 0, sizeof(vis2)); edgenum1 = edgenum2 = 0; Bcnt = Tcnt = 0; } bool ok(int n){ for(int i = 0; i < n; i++) if(!vis1[i])dfs1(i); for(int i = Tcnt -1; i>=0; i--) { if(!vis2[T[i]]) { dfs2(T[i]); Bcnt++; } } for(int i = 0; i<n; i+=2) if(belong[i] == belong[i+1]) return false; return true; } int main(){ int n, i, j; while(~scanf("%d",&n)){ n <<= 1; for(i = 0;i < n; i++)scanf("%lf %lf",&p[i].x,&p[i].y); double left = 0, right = 40000; while(right - left >= eps) { double mid = (left + right) / 2; init(); for(i = 0;i < n; i++) { for(j = i+1+!(i&1); j < n; j++) if(dist(p[i],p[j])<2*mid) { addedge(i, j^1); addedge(j, i^1); } } if(ok(n))left = mid; else right = mid; } printf("%.2lf\n",right); } return 0; }
再来一发白书板子
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #define ll double #define eps 1e-5 using namespace std; inline ll Max(ll a,ll b){return a>b?a:b;} inline ll Min(ll a,ll b){return a<b?a:b;} #define N 105*2 #define M 40000+5 struct Edge{ int to, nex; }edge[M]; int head[N], edgenum; void addedge(int u, int v){ Edge E = {v, head[u]}; edge[edgenum] = E; head[u] = edgenum ++; } bool mark[N]; int Stack[N], top; void init(){ memset(head, -1, sizeof(head)); edgenum = 0; memset(mark, 0, sizeof(mark)); } bool dfs(int x){ if(mark[x^1])return false;//一定是拆点的点先判断 if(mark[x])return true; mark[x] = true; Stack[top++] = x; for(int i = head[x]; i != -1; i = edge[i].nex) if(!dfs(edge[i].to)) return false; return true; } bool solve(int n){ for(int i = 0; i < n; i+=2) if(!mark[i] && !mark[i^1]) { top = 0; if(!dfs(i)) { while( top ) mark[ Stack[--top] ] = false; if(!dfs(i^1)) return false; } } return true; } struct Point{ double x,y; }p[N<<1]; inline double dist(Point a,Point b){return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));} int main(){ int n, i, j; while(~scanf("%d",&n)){ n <<= 1; for(i = 0;i < n; i++)scanf("%lf %lf",&p[i].x,&p[i].y); double left = 0, right = 40000; while(right - left >= eps) { double mid = (left + right) / 2; init(); for(i = 0;i < n; i++) { for(j = i+1+!(i&1); j < n; j++) if(dist(p[i],p[j])<2*mid)//冲突了 { addedge(i, j^1); addedge(j, i^1); } } if(solve(n))left = mid; else right = mid; } printf("%.2lf\n",right); } return 0; }