HDU 3834 EARTH HOUR(DIJKSTRA)
思路:建图(只要联通,边长即为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));
	}
}
posted on 2011-07-20 14:23  Eucalyptus  阅读(289)  评论(0编辑  收藏  举报