POJ 1985 Cow Marathon
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 5841 | Accepted: 2826 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
7 6 1 6 13 E 6 3 9 E 3 5 7 S 4 1 3 N 2 4 20 W 4 7 2 S
Sample Output
52
Hint
Source
Problem Idea
题目理解:农场主希望在他的地图上找到 距离彼此最远的两个农场(距离是根据两个农场之间的道路上的总长度来衡量的)。 帮助他确定这个 最远的一对农场之间的距离。
第二次对该点进行BFS,找到最长路的另一个端点,则两点之间的路径即为树的直径。
Head[i]=j 表示在邻接表中,通过头节点i,找到与其相连接的边j,这些边在邻接表的每一行都组成了一条链表, 其中第j条边是这条链的头一个元素, 接着通过j可以找到剩余的(与i连接的)边.
【输入输出要求】
接下来的M行,给出最远农场对,及其他们之间的距离的值。
<农场A> <农场B> <距离>
Source Code
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
//从任意一点u出发搜到的最远的点一定是s、t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点
// 即用两遍广搜就可以找出树的最长路
using namespace std;
const int nmax=50000+5;
const int mmax=100000+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() {
int n,m;
while(scanf("%d%d",&n,&m)==2){
cnt=0;
memset(head,-1, sizeof(head));
int u,v,cost;
char c;
for(int i=1;i<=m;i++){
scanf("%d%d%d %c",&u,&v,&cost,&c);
AddEdge(u,v,cost);
}
//getchar();
printf("%d\n",dist[BFS(BFS(u))]);//第一次对任意节点u进行BFS,找到最长路的端点
//第二次对该点进行BFS,找到最长路的另一个端点,则两点之间的路径即为树的直径
}
return 0;
}