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;
}
posted @ 2019-07-25 15:26  voids5  阅读(95)  评论(0编辑  收藏  举报