CUGB图论专场:F - Cow Marathon(邻接表+dfs的最长继承)

F - Cow Marathon
Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u
Submit  Status

Description

After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has committed to create a bovine marathon for his cows to run. The marathon route will include a pair of farms and a path comprised of a sequence of roads between them. Since FJ wants the cows to get as much exercise as possible he wants to find the two farms on his map that are the farthest apart from each other (distance being measured in terms of total length of road on the path between the two farms). Help him determine the distances between this farthest pair of farms. 

Input

* Lines 1.....: Same input format as "Navigation Nightmare".

Output

* Line 1: An integer giving the distance between the farthest pair of farms. 

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

The longest marathon runs from farm 2 via roads 4, 1, 6 and 3 to farm 5 and is of length 20+3+13+9+7=52. 

这题也是搞了好久,用到了好多种方法,用bfs超时,用通常的暴力也是超时,用平常的dfs也超时,然后也优化了可还是超时,然后想到了B题中所用的邻接表,又试写了好久,因为以前没有用过邻接表,然后对其还不是很熟,不过通过这两题的训练,终于对邻接表有了更进一步的了解了。感觉邻接表确实丈强大了,对于最短路,最小生成树,和最近公共祖先,如果运用邻接表得当的话,可以省去很多麻烦,既可以省时,也省了好多代码,简洁方便,不过就像哈希一样转来转去,确实刚开始学起来有点晕。最好的办法就是用visual studio单步运行,了解其本质,然后就好做了……

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <list>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define M 100002
#define INF 10000000
using namespace std;
typedef long long ll;
int n,m,dist[M],head[M],Max,t,i,j;
struct edge
{
    int v,l,next;   
} e[M*100];   //题目也没有n,m的范围,导致RE了一发,唉……
void add(int u,int v,int l)
{
    e[t].v=v; e[t].l=l;//邻接表,魏神有讲过,不过那时他讲也只是讲了个大概,没说用在哪里,也没有说怎么用……不过他给的教程挺好,可以自学
    e[t].next=head[u]; head[u]=t++;  //head数组是关键的,标记前一个相同的u,如没有出现过u,则为-1
}
void dfs(int u,int v,int l)
{
    dist[u]=l;
    if(l>Max) {Max=l; j=u;}
    for(int i=head[u]; i!=-1; i=e[i].next)      //这句for循环就是经典啊,邻接表的精华
        if(e[i].v!=v) dfs(e[i].v,u,l+e[i].l);
}
int main()
{
    int u,v,l;
    scanf("%d%d",&n,&m);
    mem(head,-1);
    for(i=0; i<m; i++)
    {
        scanf("%d%d%d %*c",&u,&v,&l);
        add(u,v,l); add(v,u,l);   //刚开始没用add(v,u,l); 因为得前向找儿子或者往后找祖先,所以都连通起来才得
    }
    dfs(1,0,0);   //第一次先找比较最长的
    dfs(j,0,0);   //第二次从最长的尾结点往前找就可以找到最长的了
    printf("%d\n",Max);
    return 0;
}

你可能感兴趣的:(CUGB图论专场:F - Cow Marathon(邻接表+dfs的最长继承))