Roads in the North

Roads in the North

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

题目大意:
找出距离最远的两个村庄,并输出二者之间的距离。
输入格式为:每行三个数,前两个数表示不同的村庄,最后一个数表示两个村庄之间的距离。
输出:输出距离最远村庄二者的距离。

解题思路:求树的直径模板题;需要两次bfs或dfs;先找到任意一个点,用bfs或dfs找到距离它最远的点并标记,然后以这个点为起点,用bfs或dfs找到距离它最远的点,输出二者之间的距离。
需要用到链式前向星存图及其遍历图的方式。
链式前向星存图:
加边
void add ( int u, int v, int w)
{
edge [cnt ].w = w;
edge [cnt ]. to = v;
edge [cnt ]. next = head [u];
head [u] = cnt ++;
}
cnt初始化为0,head初始化为-1

	**struct Edge
	{
		int next ;//下一条边
		int to;//这条边的终点
		int w;//边的权值
	} edge [ MAXN ];**

	边的遍历,遍历以u为起点的所有边
	for (int i= head [u];~i;i= edge [i]. next )
	{
			cout <<u<<" ->" <<edge [i].e<< endl ;
	}
		倒序遍历

Code:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define N 10000//数组大小要合适,不然会RE 
using namespace std;
struct node{
	int w,to,next;
};
node edge[N];
int cnt=0,ans=0;//如果是多组案例,cnt和ans都要更新,不更新cnt,可能会导致越界即RE 
int vis[N],head[N];
int dis[N];
int temp;
void add(int u,int v,int w){//加边 
	edge[cnt].w=w;
	edge[cnt].to=v;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}
void bfs(int x){
	queue<int >q;
	q.push(x);
	vis[x]=1;
	dis[x]=0;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=head[u];i!=-1;i=edge[i].next){//图的遍历,倒序遍历。 
			int v=edge[i].to;
			if(!vis[v]){
				if(dis[v]<dis[u]+edge[i].w){
					dis[v]=dis[u]+edge[i].w;
					if(dis[v]>ans){
						ans=dis[v];//更新边 
						temp=v;//标记端点 
					}
				}
				vis[v]=1;
				q.push(v);
			}
		}
	}
}
int main(){
	memset(head,-1,sizeof(head));//一定要将head[]初始化。 
	int u,v,w;
	while(scanf("%d %d %d",&u,&v,&w)!=EOF){//输入,用ctrl+z结束输出 
		add(u,v,w);
		add(v,u,w);
		//cout<<u<<v<<w<<endl;
	}
	bfs(1);//第一次查找 
	ans=0;
	memset(vis,0,sizeof(vis));//每次查找前都要将vis,dis归零,只有在下一个案例,才能更新head[]. 
	memset(dis,0,sizeof(dis));
	bfs(temp);//第二次查找 
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值