思路:建图(只要联通,边长即为1)对0、1、2三个顶点用3次DIJKSTRA即可解决。
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAXN 210
#define inf 1000000000
int head[MAXN], pnt[MAXN*MAXN], next[MAXN*MAXN];
int tot;
int used[3][MAXN];
double dist[3][MAXN];
struct Tpoint {
double x;
double y;
double r;
}point[MAXN];
int ncase;
int n;
void addedge (int a, int b)
{
pnt[tot]=b;
next[tot]=head[a];
head[a]=tot++;
}
double len(struct Tpoint a, struct Tpoint b)
{
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
int match(int i, int j)
{
if (len(point[i],point[j]) <= point[i].r+point[j].r) return 1;
else return 0;
}
int dijkstra (int a)
{
for (int i=0; i<n; i++) {
used[a][i]=0;
dist[a][i]=inf;
}
dist[a][a]=0;
for (int i=0; i<n; i++) {
int min=inf,minp;
for (int j=0; j<n; j++) {
if(!used[a][j] && dist[a][j]<min) {
min=dist[a][j];
minp=j;
}
}
if(min==inf) return 0;
used[a][minp]=1;
int idx=head[minp];
while (~idx) {
if(!used[a][pnt[idx]] && dist[a][minp] + 1.0 < dist[a][pnt[idx]]) //length[idx]=1
dist[a][pnt[idx]]=dist[a][minp] + 1.0;
idx=next[idx];
}
}
return 1;
}
int main()
{
scanf("%d",&ncase);
while (ncase--) {
tot=0;
memset (head,-1,sizeof(head));
memset (next,-1,sizeof(next));
scanf ("%d",&n);
for (int i=0; i<n; i++) {
scanf ("%lf%lf%lf",&point[i].x,&point[i].y,&point[i].r);
for (int j=0; j<i;j++) {
if (match(i,j)) {
//printf("%d %d %lf\n",i,j,len(point[i],point[j]));
addedge(i,j);
addedge(j,i);
}
}
}
for (int i=0; i<3; i++)
dijkstra(i);
//for(int i=0; i<n; i++)
// printf("%d:%.3lf\n",i,dist[0][i]);
int min=inf,minp;
for(int i=0; i<n; i++) {
if (dist[0][i]+dist[1][i]+dist[2][i] < min) {
min=dist[0][i]+dist[1][i]+dist[2][i];
minp=i;
}
}
if(min==inf) printf("-1\n");
else printf("%d\n",n-(min+1));
}
}
浙公网安备 33010602011771号