//内存没开够会运行错误,开够了 就超时了....以下第一个只有75分,改成和两次Dfs差不多的形式(即两次bfs)就可以了,感觉 我的这个有点像迪杰斯特拉或者SPFA(当时是照着用vector模拟邻接表做的,刚好里面求得是最短路径,,然后 按他的说法,是属于SPFA,,具体的我不清楚).......但是 求得 是最长路径.....不过感觉这种写着没有直接DFS(直接更新起始点到目前所到点的距离)来的简洁。。。。
用两次求得最长路径的思想是:https://blog.csdn.net/llwwlql/article/details/53914447
1) 如果w 是直径上的点,则v显然是直径的终点(因为如果v不是的话,则必定存在另一个点x使得w到x的距离更长,则与d(u,v)为直径冲突)
2)如果w不是直径上的点,则w到v必然于树的直径相交(反证),那么交点到v 必然就是直径的后半段了,所以v一定是直径的一个端点,所以从v进行DFS得到的一定是直径长度
#include<iostream>
#include<cstdio>
#include<string.h>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 10000+5;
const int inf = 0x3f3f3f;
struct Node{
int u, v, w;
}dis[N];
bool cmp(Node a, Node b){
return a.w < b.w;
}
vector<Node> Head[N];
bool vis[N];
int n;
//初始化
void init()
{
for(int i=1; i<N; i++){
dis[i].v = i;
dis[i].u = i;
dis[i].w = 0;
}
for(int i=1; i<N; i++){
vis[i] = false;
}
}
//构造邻接表
void AddEdge(int u, int v, int w)
{
Node tmp;
tmp.v = v, tmp.w = w;
Head[u].push_back(tmp);
}
void UpdateDis()
{
int MAX = 0;
for(int i=1; i<=n; i++)
{
queue<int> q;
init();
q.push(i);
dis[i].w = 0;
vis[i] = true;
while(!q.empty()){
int tmp = q.front();
q.pop();
for(int i=0; i<Head[tmp].size(); i++){
int u = tmp, v = Head[tmp].at(i).v, w = Head[tmp].at(i).w;
if(!vis[v] && dis[v].w < dis[u].w + w){//求最长的距离
dis[v].w = dis[u].w+w;
dis[u].v = v;
// dis[u].u = u;
//if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
sort(dis+1, dis+1+n, cmp);
MAX = max(MAX, dis[n].w);
// cout << dis[n].u <<" " << dis[n].v <<" " << dis[n].w << endl;
}
cout << MAX*10+(MAX+1)*MAX/2 << endl;
}
int main()
{
cin >> n;
for(int i=1; i<n; i++){
int a, b, c;
cin >> a >> b >> c;
AddEdge(a, b, c);
AddEdge(b, a, c);
}
UpdateDis();
return 0;
}
AC代码
//https://blog.csdn.net/llwwlql/article/details/53914447 两次dfs求出树的直径
#include<iostream>
#include<cstdio>
#include<string.h>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 10000+5;
const int inf = 0x3f3f3f;
struct Node{
int u, v, w;
}dis[N];
bool cmp(Node a, Node b){
return a.w < b.w;
}
vector<Node> Head[N];
bool vis[N];
int n;
//初始化
void init()
{
for(int i=1; i<N; i++){
dis[i].v = i;
dis[i].u = i;
dis[i].w = 0;
}
for(int i=1; i<N; i++){
vis[i] = false;
}
}
//构造邻接表
void AddEdge(int u, int v, int w)
{
Node tmp;
tmp.v = v, tmp.w = w;
Head[u].push_back(tmp);
}
void UpdateDis(int i)
{
int MAX = 0;
//for(int i=1; i<=n; i++)
{
queue<int> q;
init();
q.push(i);
dis[i].w = 0;
vis[i] = true;
while(!q.empty()){
int tmp = q.front();
q.pop();
for(int i=0; i<Head[tmp].size(); i++){
int u = tmp, v = Head[tmp].at(i).v, w = Head[tmp].at(i).w;
if(!vis[v] && dis[v].w < dis[u].w + w){//求最长的距离
dis[v].w = dis[u].w+w;
dis[u].v = v;
// dis[u].u = u;
//if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
sort(dis+1, dis+1+n, cmp);
// MAX = max(MAX, dis[n].w);
// cout << dis[n].u <<" " << dis[n].v <<" " << dis[n].w << endl;
}
// cout << MAX*10+(MAX+1)*MAX/2 << endl;
}
int main()
{
cin >> n;
for(int i=1; i<n; i++){
int a, b, c;
cin >> a >> b >> c;
AddEdge(a, b, c);
AddEdge(b, a, c);
}
UpdateDis(1);
int start = dis[n].v;
UpdateDis(start);
int MAX = dis[n].w;
cout << MAX*10+(MAX+1)*MAX/2 << endl;
return 0;
}