 /**//*
n<=200個(gè)點(diǎn)的無向圖,要求前3個(gè)點(diǎn)需要連接在一起,求最多能刪除的其余點(diǎn)

連在一起,想到生成樹
再畫下這3個(gè)點(diǎn)連在一起的形狀,要不就是一條鏈,要不就是 一個(gè)中心點(diǎn)連接這3個(gè)點(diǎn)
可以枚舉那個(gè)中心點(diǎn)u(鏈的情況是中心點(diǎn)為那3個(gè)點(diǎn)的情況)
然后bfs,再標(biāo)記u到三個(gè)點(diǎn)的路徑,其余點(diǎn)就是可以去掉的

有點(diǎn)慢
看了別人的,反過來,是計(jì)算那3個(gè)點(diǎn)bfs到其余點(diǎn),然后再枚舉中間點(diǎn)u
標(biāo)記前3個(gè)點(diǎn)到u的路徑

反過來從目標(biāo)bfs出去,少計(jì)算很多呀!! ---------------OMG

這道題應(yīng)該是因?yàn)橹挥?個(gè)點(diǎn),最多只需一個(gè)中間點(diǎn)連接~~~~
>3時(shí),恐怕就不行了吧,比如這題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
搜索
最新評(píng)論

|
|