POJ-2631 Roads in the North (bfs求树的直径)

轻触即可到北大OJ一次游

先看题目:

Roads in the North

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5968 Accepted: 2817

Description

Building and maintaining roads among communities in the far North is an expensive business. With this in mind, the roads are build such that there is only one route from a village to a village that does not pass through some other village twice. 
Given is an area in the far North comprising a number of villages and roads among them such that any village can be reached by road from any other village. Your job is to find the road distance between the two most remote villages in the area. 

The area has up to 10,000 villages connected by road segments. The villages are numbered from 1. 

Input

Input to the problem is a sequence of lines, each containing three positive integers: the number of a village, the number of a different village, and the length of the road segment connecting the villages in kilometers. All road segments are two-way.

Output

You are to output a single integer: the road distance between the two most remote villages in the area.

Sample Input

5 1 6
1 4 5
6 3 9
2 6 8
6 1 7

Sample Output

22

在遥远的北方有很多村庄,任何村庄都可以从任何其他村庄通过公路到达。你的工作是找出该地区两个最偏远的村庄之间的道路距离。

很明显这是一棵树,最远的距离即为树的直径,我也是刚学的,我不会告诉你树的直径需要两遍搜索,第一次是从某个点找到树的一个端点,第二次是从这个端点出发找到树的另一个端点,最远的两个端点的距离就是树的直径

据说需要搭建一个静态链表,之前上课没好好听,知道这个东西却不会用,听大佬说这是个板子,那我就先不解释了,我也就跟着背板子了    Orz

关于静态链表,弱鸡表示只会背板子,不是很理解,这里有一个解释的很详细的博客

还有这个题的注意事项,多组输入没有结束点就很烦,因为你不能去测样例。。。再者就是关于静态链表的搭建问题,我居然把忘了初始化静态链表的尾。。。还调了老半天,可长了记性了。。。

最难的就是本题的主要过程  搜索,要学着怎么用搜索去遍历一个图,可以用bfs也可以用dfs,看个人习惯,我感觉dfs太抽象而且开销大,不如bfs好理解。见好多大佬都喜欢用dfs,可能是我太弱鸡了吧!有空我一定去练习一下自己的深搜    Orz

弱弱地奉上本弱鸡的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int mm=1e6+5;
struct node{
	int x,y,len,next;
}pp[mm];
//搭建一个静态链表 
int head[mm];
int num=0;
void add(int x,int y,int z){ 
	pp[num].x=x;
	pp[num].y=y;
	pp[num].len=z;
	pp[num].next=head[x];
	head[x]=num++;//存路径信息 
}

queue<int>q;
int book[mm],dis[mm];
int end,res;
int bfs(int n){//广搜求树的直径 
	memset(book,0,sizeof(book));
	memset(dis,0,sizeof(dis));
	
	book[n]=1;
	dis[n]=0;
	q.push(n);
	res=0;
	
	while(!q.empty()){
		int t=q.front();
		q.pop();
		for(int i=head[t];i!=-1;i=pp[i].next){//!!! 
			int y=pp[i].y;
			if(book[y]==0&&dis[y]<dis[t]+pp[i].len){//找到离当前点最远的距离 
				dis[y]=dis[t]+pp[i].len;
				if(res<dis[y]){
					res=dis[y];
					end=y;
				}
				book[y]=1;
				q.push(y);
			}
		}
	}
	return res;
}

int main()
{
	int a,b,c;
	memset(head,-1,sizeof(head));//!!!居然给忘了。。。 
	while(scanf("%d%d%d",&a,&b,&c)!=EOF){// 最烦这种玩意了,不能测样例~_~ 
		add(a,b,c);
		add(b,a,c);
	}
	bfs(1);
	res=bfs(end);
	printf("%d\n",res);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值