TYVJ 1069 cowtour 解题报告

  USACO原题,做过几次了,所以一次AC,就是暴搜,因为数据小。

  先把每个牧区的直径求出来,然后再把在一个牧区中距离任意节点的最远距离算出来,然后暴搜,若i,j之间加一条路,那么新牧区的半径要么就是i所在的牧区的的直径,要么是j所在的牧区的直径,要么就是i所在的牧区中距i最远的距离加上j所在的牧区中距j最远的距离加上i,j之间的距离。
  看代码最有效:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define INF 100000000
struct dot{
	int x, y;
}dot[150];
int n;
double dis[150][150];
double dir[150];
int group[150];
double maxdis[150];
char can[150][150];

double getdis(int a, int b)
{
	double t;
	t = sqrt((double)(dot[a].x - dot[b].x) * (dot[a].x - dot[b].x) +
		(dot[a].y - dot[b].y) * (dot[a].y - dot[b].y));
	return t;
}

void makegroup(int a, int b)
{
	int i;
	group[a] = b;
	for(i = 0; i < n; i++){
		if(can[a][i] && group[i] != b){
			makegroup(i, b);
		}
	}
}

void init(void)
{
	int i, j;
	scanf("%d\n", &n);
	for(i = 0; i < n; i++){
		scanf("%d%d\n", &dot[i].x, &dot[i].y);
	}
	for(i = 0; i < n; i++){
		for(j = 0; j < n; j++){
			scanf("%c", &can[i][j]);
			can[i][j] -= '0';
			//确实不知道这个i == j, dis = 0可以影响程序的运行
			//刚刚仔细查了一下, 原来是在获取dis[i][i]的时候得到了错误的值(非0)
			//然后再计算半径的时候就使用了那个错误的较大的值, 导致程序错了.
			if(i == j){
				dis[i][j] = 0;
			}else if(can[i][j] == 0){
				dis[i][j] = INF;
			}else{
				dis[i][j] = getdis(i, j);
			}
		}
		scanf("\n");
	}
}

int main(int argc, char **argv)
{
	int i, j, k;
	double ans = INF, t;
	init();
	for(i = 0, j = 1; i < n; i++){
		if(!group[i]){
			makegroup(i, j);
			j++;
		}
	}
	for(k = 0; k < n; k++){
		for(i = 0; i < n; i++){
			for(j = 0; j < n; j++){
				if(group[i] == group[j] && group[i] == group[k]){
					if(dis[i][j] > dis[i][k] + dis[k][j]){
						dis[i][j] = dis[i][k] + dis[k][j];
					}
				}
			}
		}
	}
	for(i = 0; i < n; i++){
		for(j = 0; j < n; j++){
			if(group[i] == group[j] && dir[group[i]] < dis[i][j]){
				dir[group[i]] = dis[i][j];
			}
			if(group[i] == group[j] && maxdis[i] < dis[i][j]){
				maxdis[i] = dis[i][j];
			}
		}
	}
	for(i = 0; i < n; i++){
		for(j = 0; j < n; j++){
			if(group[i] == group[j]){
				continue;
			}
			t = maxdis[i] + maxdis[j] + getdis(i, j);
			if(t < dir[group[i]]){
				t = dir[group[i]];
			}
			if(t < dir[group[j]]){
				t = dir[group[j]];
			}
			if(ans > t){
				ans = t;
			}
		}
	}
	printf("%.6lf", ans);
	return 0;
}

posted @ 2011-07-06 20:53  zqynux  阅读(212)  评论(0编辑  收藏  举报