[POJ 2349] Arctic Network
[题目链接]
http://poj.org/problem?id=2349
[算法]
首先,我们发现答案是具有单调性的,所以我们可以二分答案
检验时,我们将所有距离小于二分值的点连边,然后判断联通块数量是否小于等于S即可
[代码]
#include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXP 1010 const int INF = 2e9; const double eps = 1e-4; struct edge { int to,nxt; } e[MAXP * MAXP * 2]; int i,j,S,P,T,tot; int head[MAXP]; bool visited[MAXP]; pair<double,double> a[MAXP]; double l,r,mid,ans; inline double dist(pair<double,double> a,pair<double,double> b) { return sqrt((a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second)); } inline void addedge(int u,int v) { tot++; e[tot] = (edge){v,head[u]}; head[u] = tot; } inline void bfs(int s) { int i,l,r,u,v; static int q[MAXP]; q[l = r = 1] = s; while (l <= r) { u = q[l]; l++; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; if (!visited[v]) { q[++r] = v; visited[v] = true; } } } } inline bool check(double mid) { int i,j,cnt = 0; tot = 0; memset(head,0,sizeof(head)); memset(visited,false,sizeof(visited)); for (i = 1; i <= P; i++) { for (j = i + 1; j <= P; j++) { if (dist(a[i],a[j]) <= mid) { addedge(i,j); addedge(j,i); } } } for (i = 1; i <= P; i++) { if (!visited[i]) { visited[i] = true; cnt++; bfs(i); } } return cnt <= S; } int main() { scanf("%d",&T); while (T--) { scanf("%d%d",&S,&P); for (i = 1; i <= P; i++) scanf("%lf%lf",&a[i].first,&a[i].second); l = 1; r = 10000; while (r - l > eps) { mid = (l + r) / 2; if (check(mid)) { ans = mid; r = mid; } else l = mid; } printf("%.2f\n",ans); } return 0; }