USACO Cow Tours, Floyed-Warshall, FloodFill(BFS)

参考思路:
http://kaolausaco.blogbus.com/logs/62563337.html
http://www.byvoid.com/blog/usaco-243-cow-tours/
http://www.cppblog.com/yuziyu/archive/2009/06/27/88662.html

我的思路:
1. 根据最开始的联通图信息,求出原始的distance数组
2. FloodFill, 求出联通分量的个数(color)
3. floyed,求出每个顶点到其余各顶点的距离,更新dist数组
4. 根据最新的dist数组,求出每个顶点在可到达范围内的最大距离maxD,以及每个联通分量内部最远距离maxCC
5. 遍历dist[i][j],如果i和j不在一个联通分量里,就尝试连接,并且记录下连接的最短的那对点
6. 最短的直径为以下三者中最大值   maxD[i] + maxD[j] + dist(i,j) , i所在联通分量的最大直径, j所在联通分量的最大直径 

我的代码:

/* 
ID: wangxin12 
PROG: cowtour
LANG: C++ 
*/ 
#include <iostream>
#include <vector>
#include <fstream>
#include <queue>
#include <math.h>
#include <iomanip>
using namespace std;
#define MAX 150

struct pt {
	int x;
	int y;
	int CC;
};

struct pt point[MAX + 1];
bool connected[MAX + 1][MAX + 1];
double dist[MAX + 1][MAX + 1];
bool visited[MAX + 1];  //floodfill使用
int color = 0;  //floodfill使用,最后记载联通分量的个数
int N;
vector<double> maxCC;   //每个联通分量内部的最大距离
double maxD[MAX + 1];  //每个点距离自己connect的点的最远的距离

double getDist(pt p1, pt p2); 
void floyed();
void floodFill(int order);

int main() {
	ifstream fin("cowtour.in");
	ofstream fout("cowtour.out");

	int i, j;
	//read data
	fin>>N;
	for(i = 1; i <= N; i++) {
		fin>>point[i].x>>point[i].y;
	}
	for(i = 1; i <= N; i++) {
		for(j = 1; j <= N; j++) {
			char temp;
			fin>>temp;
			if(temp == '1')
				connected[i][j] = true;
		}
	}

	//floodFill
	for(j = 1; j <= N; j++) {
		floodFill(j);
	}

	//init distance
	for(i = 1; i <= N; i++) {
		for(j = 1; j <= N; j++) {
			if(i == j) {
				dist[i][j] = 0;
				continue;
			}
			if(connected[i][j])
				dist[i][j] = getDist(point[i], point[j]);
			else
				dist[i][j] = 999999;
		}
	}
	
	//
	floyed();

	//find the longest dis in every CC
	j = 0;
	while(j <= color) {
		maxCC.push_back(0);
		j++;
	}
	for(i = 1; i <= N; i++) {
		int index = point[i].CC;
		for(j = 1; j <= N; j++) {
			if(dist[i][j] < 999990)
				maxCC[index] = (maxCC[index] >= dist[i][j]) ? maxCC[index] : dist[i][j] ;
		}
	}

	//find the longest dis of every point
	for(i = 1; i <= N; i++) {
		for(j = 1; j <= N; j++) {
			if(dist[i][j] > maxD[i] && dist[i][j] < 999999)
				maxD[i] = dist[i][j];
		}
	}

	//
	double minDis = 999999;
	int source, dest;
	for(i = 1; i <= N; i++) {
		for(j = 1; j <= N; j++) {
			if(point[i].CC == point[j].CC)
				break;

			double temp;
			temp = maxD[i] + maxD[j] + getDist(point[i], point[j]);
			
			//double dia1, dia2;
			//dia1 = maxCC[point[i].CC];
			//dia2 = maxCC[point[j].CC];
			//
			//temp = (temp >= dia1) ? temp : dia1 ;
			//temp = (temp >= dia2) ? temp : dia2 ;

			if(temp < minDis) {
				minDis = temp;
				source = i;
				dest = j;
			}
		}
	}

	double dia1, dia2;
	dia1 = maxCC[point[source].CC];
	dia2 = maxCC[point[dest].CC];
			
	minDis = (minDis >= dia1) ? minDis : dia1 ;
	minDis = (minDis >= dia2) ? minDis : dia2 ; 

	fout<<fixed<<setprecision(6)<<minDis<<endl;

	return 0;
}

double getDist(pt p1, pt p2) {
	return sqrt((double)(p1.x-p2.x)*(p1.x-p2.x)+(double)(p1.y-p2.y)*(p1.y-p2.y));
}

void floyed() {
	for(int k = 1; k <= N; k++) {
		for(int i = 1; i <= N; i++) {
			for(int j = 1; j <= N; j++) {
				if(k != i && k != j)
				dist[i][j] = (dist[i][j] <= dist[i][k] + dist[k][j]) ? dist[i][j] : dist[i][k] + dist[k][j] ;
			}
		}
	}
}

void floodFill(int order) {
	if(visited[order]) return;
	
	color++;
	queue<int> que;
	que.push(order);
	visited[order] = true;

	while(!que.empty()) {
		int tmp;
		tmp = que.front();
		que.pop();
		point[tmp].CC = color;
		visited[tmp] = true;

		for(int j = 1; j <= N; j++) {
			if(connected[tmp][j] && !visited[j])
				que.push(j);
		}
	}
}






-------------------------------------------------------------------------

Cow Tours

Farmer John has a number of pastures on his farm. Cow paths connect some pastures with certain other pastures, forming a field. But, at the present time, you can find at least two pastures that cannot be connected by any sequence of cow paths, thus partitioning Farmer John's farm into multiple fields.

Farmer John would like add a single a cow path between one pair of pastures using the constraints below.

A field's `diameter' is defined to be the largest distance of all the shortest walks between any pair of pastures in the field. Consider the field below with five pastures, located at the points shown, and cow paths marked by lines:

                15,15   20,15
                  D       E
                  *-------*
                  |     _/|
                  |   _/  |
                  | _/    |
                  |/      |
         *--------*-------*
         A        B       C
         10,10   15,10   20,10

The `diameter' of this field is approximately 12.07106, since the longest of the set of shortest paths between pairs of pastures is the path from A to E (which includes the point set {A,B,E}). No other pair of pastures in this field is farther apart when connected by an optimal sequence of cow paths.

Suppose another field on the same plane is connected by cow paths as follows:

                         *F 30,15
                         / 
                       _/  
                     _/    
                    /      
                   *------ 
                   G      H
                   25,10   30,10

In the scenario of just two fields on his farm, Farmer John would add a cow path between a point in each of these two fields (namely point sets {A,B,C,D,E} and {F,G,H}) so that the joined set of pastures {A,B,C,D,E,F,G,H} has the smallest possible diameter.

Note that cow paths do not connect just because they cross each other; they only connect at listed points.

The input contains the pastures, their locations, and a symmetric "adjacency" matrix that tells whether pastures are connected by cow paths. Pastures are not considered to be connected to themselves. Here's one annotated adjacency list for the pasture {A,B,C,D,E,F,G,H} as shown above:

                A B C D E F G H
              A 0 1 0 0 0 0 0 0
              B 1 0 1 1 1 0 0 0
              C 0 1 0 0 1 0 0 0
              D 0 1 0 0 1 0 0 0
              E 0 1 1 1 0 0 0 0
              F 0 0 0 0 0 0 1 0
              G 0 0 0 0 0 1 0 1
              H 0 0 0 0 0 0 1 0

Other equivalent adjacency lists might permute the rows and columns by using some order other than alphabetical to show the point connections. The input data contains no names for the points.

The input will contain at least two pastures that are not connected by any sequence of cow paths.

Find a way to connect exactly two pastures in the input with a cow path so that the new combined field has the smallest possible diameter of any possible pair of connected pastures. Output that smallest possible diameter.

PROGRAM NAME: cowtour

INPUT FORMAT

Line 1:An integer, N (1 <= N <= 150), the number of pastures
Line 2-N+1:Two integers, X and Y (0 <= X ,Y<= 100000), that denote that X,Y grid location of the pastures; all input pastures are unique.
Line N+2-2*N+1:lines, each containing N digits (0 or 1) that represent the adjacency matrix as described above, where the rows' and columns' indices are in order of the points just listed.

SAMPLE INPUT (file cowtour.in)

8
10 10
15 10
20 10
15 15
20 15
30 15
25 10
30 10
01000000
10111000
01001000
01001000
01110000
00000010
00000101
00000010

OUTPUT FORMAT

The output consists of a single line with the diameter of the newly joined pastures. Print the answer to exactly six decimal places. Do not perform any special rounding on your output.

SAMPLE OUTPUT (file cowtour.out)

22.071068

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值