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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章