数的直径算法入门

    当每个人第一次听到树的直径这个算法的时候都fei'非常奇怪吧!树的直径?什么鬼?难道是要求一个树的直径?哈哈,怎么可能,我们总不能求一个树的直径吧!当然不是,其实这只是一种形象的比喻,我们所求的就是一个树中所有节点中最最长的那两个点的距离,因为是这个树的最大距离,所以就形象的比喻为树的直径了。

 首先先jian简单的介绍一下什么是树吧,先用gua官方用语介绍一下:

树(tree)是包含n(n>0)个结点的有穷集,其中: 每个元素称为结点(node); 有一个特定的结点被称为根结点或树根(root); 除根结点之外的其余数据元素被分为m(m≥0)个互不相交 的集合T1,T2,…Tm−1,其中每一个集合Tm−1(1≤i≤m) 本身也是一棵树,被称作原树的子树(subtree)。

 其实大致意思就是有很多的点连接起来,而且也没有连成环,形成了大致上一个树的xing形状,这就是树了;

树中距离最大的两个结点之间的距离称为树的直径:

看一下这个树,我们很容易看出来,距离 最远的两个点就是s->v这两个点,那么这两个点之间的距离就是这个树的直径,原理我们是知道了,关键是我们怎么把树的直径给求出来呢?

其实吧!这也不难,两次dfs或bfs。第一次任意选一个点进行dfs(bfs)找到离它最远的 点,此点就是最长路的一个端点,再以此点进行dfs(bfs),找到 离它最远的点,此点就是最长路的另一个端点,于是就找到了树 的直径。                                                          至于为什么这样求出来的就是树的直径,在这里先不做证明,因为我也不会,哈哈。

这里介绍用BFS来求树的直径,自我感觉BFS更容易理解。下面紧跟一道例题来去求树的直径。

The northern part of the Pyramid contains a very large and complicated labyrinth. The labyrinth is divided into square blocks, each of them either filled by rock, or free. There is also a little hook on the floor in the center of every free block. The ACM have found that two of the hooks must be connected by a rope that runs through the hooks in every block on the path between the connected ones. When the rope is fastened, a secret door opens. The problem is that we do not know which hooks to connect. That means also that the neccessary length of the rope is unknown. Your task is to determine the maximum length of the rope we could need for a given labyrinth.

Input

The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing two integers C and R (3 <= C,R <= 1000) indicating the number of columns and rows. Then exactly R lines follow, each containing C characters. These characters specify the labyrinth. Each of them is either a hash mark (#) or a period (.). Hash marks represent rocks, periods are free blocks. It is possible to walk between neighbouring blocks only, where neighbouring blocks are blocks sharing a common side. We cannot walk diagonally and we cannot step out of the labyrinth. 
The labyrinth is designed in such a way that there is exactly one path between any two free blocks. Consequently, if we find the proper hooks to connect, it is easy to find the right path connecting them.

Output

Your program must print exactly one line of output for each test case. The line must contain the sentence "Maximum rope length is X." where Xis the length of the longest path between any two free blocks, measured in blocks.

Sample Input

2
3 3
###
#.#
###
7 6
#######
#.#.###
#.#.###
#.#.#.#
#.....#
#######

Sample Output

Maximum rope length is 0.
Maximum rope length is 8.

Hint

Huge input, scanf is recommended. 
If you use recursion, maybe stack overflow. and now C++/c 's stack size is larger than G++/gcc

这道题就是一道典型的求shu树的直径的题,

下面是AC代码:

#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
struct stu
{
	int x;
	int y;
	int step;
}e1,e2,f;
char a[1003][1003];
bool A[1003][1003];
int n,m,ans;
int d[4][2]={1,0,-1,0,0,1,0,-1};
void bfs(int x,int y)
{
	memset(A,0,sizeof(A));
	e1.step=0;
	e1.x=x;e1.y=y;
	A[x][y]=1;
	queue<stu>q;
	q.push(e1);
	ans=-1;
	while(!q.empty())
	{
		e1=q.front();
		q.pop();
		if(e1.step>ans)
		{
			ans=e1.step;
			f.x=e1.x;
			f.y=e1.y;
		}
		for(int i=0;i<4;i++)
		{
			e2.x=e1.x+d[i][0];
			e2.y=e1.y+d[i][1];
			if(e2.x>=0&&e2.x<n&&e2.y>=0&&e2.y<m&&A[e2.x][e2.y]==0&&a[e2.x][e2.y]!='#')
			{
				e2.step=e1.step+1;
				A[e2.x][e2.y]=1;
				q.push(e2);
			}
		}
	}
	
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d %d",&m,&n);
		for(int i=0;i<n;i++)
			scanf("%s",a[i]);
		int cnt=0,edx,edy;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				if(a[i][j]=='.')
				{
					cnt=1;
					edx=i;
					edy=j;
					break;
				}
				if(cnt) break;
			}
		}
		bfs(edx,edy);//第一次BFS;
		bfs(f.x,f.y);//第二次:
		printf("Maximum rope length is %d.\n",ans);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42757965/article/details/82015905