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
这题也是搞了好久,用到了好多种方法,用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; }