/**//* n<=200个点的无向图,要求前3个点需要连接在一起,求最多能删除的其余点
连在一起,想到生成树 再画下这3个点连在一起的形状,要不就是一条链,要不就是 一个中心点连接这3个点 可以枚举那个中心点u(链的情况是中心点为那3个点的情况) 然后bfs,再标记u到三个点的路径,其余点就是可以去掉的
有点慢 看了别人的,反过来,是计算那3个点bfs到其余点,然后再枚举中间点u 标记前3个点到u的路径
反过来从目标bfs出去,少计算很多呀!! ---------------OMG
这道题应该是因为只有3个点,最多只需一个中间点连接~~~~ >3时,恐怕就不行了吧,比如这题hdu 3311 */ #include<iostream> #include<cstring> #include<map> #include<algorithm> #include<stack> #include<queue> #include<cstring> #include<cmath> #include<string> #include<cstdlib> #include<vector> #include<cstdio> #include<set> #include<list> #include<numeric> #include<cassert> #include<sstream> #include<ctime> #include<bitset> #include<functional>
using namespace std;
const int INF = 0x3f3f3f3f; const double EPS = 1e-8; const int MAXN = 210;
#define sqr(x) ((x)*(x))
struct Light { double x, y, r; void read() { scanf("%lf%lf%lf", &x, &y, &r); } bool isIntersect(Light &B) { return sqr(x - B.x) + sqr(y-B.y) - EPS < sqr(r+B.r); } };
Light light[MAXN]; vector<int> e[MAXN]; int vi[MAXN], dist[3][MAXN], pre[3][MAXN];
int main() { #ifndef ONLINE_JUDGE freopen("in","r",stdin); #endif
int T, n; for (scanf("%d", &T); T--; ) { scanf("%d", &n); for (int i = 0; i < n; i++) { e[i].clear(); light[i].read(); } for (int i = 0; i < n; i++) { for (int j = i+1; j < n; j++) { if (light[i].isIntersect(light[j])) { e[i].push_back(j); e[j].push_back(i); } } } for (int s = 0; s < 3; s++) { fill(dist[s], dist[s]+MAXN, INF); fill(pre[s], pre[s]+MAXN, -1); dist[s][s] = 0; queue<int> q; q.push(s); while (!q.empty()) {//bfs int v = q.front(); q.pop(); for (vector<int>::iterator it = e[v].begin(); it != e[v].end(); it++) { if (dist[s][*it] == INF) { dist[s][*it] = dist[s][v]+1; pre[s][*it] = v; q.push(*it); } } } }
int ans = -1; for (int u = 0; u < n; u++) { fill(vi, vi+n, 0); for (int s = 0; s < 3; s++) { if (dist[s][u] != INF) { int p = u; do { vi[p] = 1; p = pre[s][p]; }while (p != -1); } } if (vi[0] && vi[1] && vi[2]) { ans = max(ans, n - count(vi, vi+n, 1)); } } printf("%d\n", ans); } return 0; }
|
|
常用链接
随笔分类
Links
搜索
最新评论
|
|