今天学习了树的直径,这道题算是入门题吧,即便这样,还是对照着大神的代码敲完的。。
这好不容易写完了,又提交了N遍,刚开始是Runtime Error,找了半天原来是数组开小了,导致运行中数组越界;
上个问题刚处理好,一提交又变成了Wrong Answer!!原来是在找最长边是,i的值要从1开始到等于n结束。。
好吧,先上点儿定义:树是n(n>=0)结点的有限集,是一个无向联通无环图。n=0时自然就是空树啦!当n>0时,树有且仅有一个根节点,树上的任意两点间的距离是唯一的。
树的直径的证明主要用到了反证法:参考大神的证明过程
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define MAXN 40000+10
using namespace std;
struct Edge {
int to;//边的终点
int val;//边的长度
int next;//下一条边的起点
}edge[80000+10];
int dist[MAXN];//记录两点之间的距离
bool vis[MAXN];//判断该点是否被访问过
int head[MAXN];//一条边的终点,也是另一条边的起点
int top;//边
int n,m;
int ans;//存放最大距离
int node;//存放树的直径端点S或T
void init(){
top = 0;
memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int w) {
Edge E={v,w,head[u]};
edge[top]=E;
head[u]=top++;
}//树的存储,类似于邻接表
void getmap(){
int a,b,c;
char op[2];
while(m--){
scanf("%d%d%d%s",&a,&b,&c,op);
addEdge(a,b,c);
addEdge(b,a,c);//按端点正反两次
}
}
void BFS(int sx) {
queue<int> Q;
memset(dist, 0, sizeof(dist));
memset(vis, false, sizeof(vis));
node=sx;
ans = 0;
vis[sx] = true;
Q.push(sx);
while(!Q.empty()) {
int u = Q.front();
Q.pop();
for(int i=head[u];i!=-1;i=edge[i].next) {
Edge E=edge[i];
if(!vis[E.to]) {
dist[E.to]=dist[u]+E.val;
vis[E.to] = true;
Q.push(E.to);
}
}
}
for(int i = 1; i <= n; i++) {//i要从1开始。。
if(ans < dist[i]) {
ans = dist[i];
node = i;
}
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
init();//初始化
getmap();
BFS(1);
BFS(node);
printf("%d\n",ans);
}
return 0;
}