POJ 2631 Roads in the North
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3239 | Accepted: 1615 |
Description
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
Output
Sample Input
5 1 6 1 4 5 6 3 9 2 6 8 6 1 7
Sample Output
22
Source
Problem Idea
题目理解:鉴于北部最远的一个地区,其中包括一些村庄和道路,这样任何村庄都可以从任何其他村庄通过公路到达。
第二次对该点进行BFS,找到最长路的另一个端点,则两点之间的路径即为树的直径。
Head[i]=j 表示在邻接表中,通过头节点i,找到与其相连接的边j,这些边在邻接表的每一行都组成了一条链表, 其中第j条边是这条链的头一个元素, 接着通过j可以找到剩余的(与i连接的)边.
【输入输出要求】
<村庄A> <村庄B> <距离>
Source Code
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
//从任意一点u出发搜到的最远的点一定是s、t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点
// 即用两遍广搜就可以找出树的最长路
using namespace std;
const int nmax=10000+5;
const int mmax=1000000+5;
struct Edge{
int to,cost,next;//边尾部,边距离,指向下条边
Edge(){}
Edge(int to,int cost,int next):to(to),cost(cost),next(next){}
}edges[mmax];
int cnt=0;//边总数
int head[nmax];//邻接表的头结点
void AddEdge(int u,int v,int cost){//在邻接表中添加两条有向边
edges[cnt]=Edge(v,cost,head[u]);
head[u]=cnt++;
edges[cnt]=Edge(u,cost,head[v]);
head[v]=cnt++;
}
int dist[nmax];//当前的最远距离,dist[i]表示当前点到点i的距离;
int BFS(int s){//BFS返回从s出发能到达的最远点编号
int maxdist=0;//记录最远距离
int id=s;//记录最远节点,初始化为s
queue<int> q;
memset(dist,-1, sizeof(dist));
dist[s]=0;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();//出队头元素
if(dist[u]>maxdist){
maxdist=dist[id=u];//更新最远距离,同时记录最远点的id
}
//main中需要初始化// memset(head,-1, sizeof(head));
for(int i=head[u];i!=-1;i=edges[i].next){//如果u节点还未被访问,则访问u节点;之后再访问edges[i].next节点
Edge &e=edges[i];
if(dist[e.to]==-1){
dist[e.to]=dist[u]+e.cost;//如若未被访问,则更新当前的最远距离
q.push(e.to);
}
}//end of for
}//end of while
return id;
}
int main() {
cnt=0;
memset(head,-1, sizeof(head));
int u,v,cost;
while(scanf("%d%d%d",&u,&v,&cost)==3){
AddEdge(u,v,cost);
}
//getchar();
printf("%d\n",dist[BFS(BFS(u))]);//第一次对任意节点u进行BFS,找到最长路的端点
//第二次对该点进行BFS,找到最长路的另一个端点,则两点之间的路径即为树的直径
return 0;
}