思路:本题就是求在树上 MAX(dis[A,B]+MIN(dis[A,C]+dis[B,C]))
可以证明AB是树上最长链
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 #define MAXN 200001 7 struct node 8 { 9 int num; 10 long long weight; 11 node *next; 12 }; 13 node *graph[MAXN],memo[2*MAXN]; 14 int father[MAXN],dp[MAXN],Q[MAXN],path[MAXN]; 15 long long d1[MAXN],d2[MAXN]; 16 int n,m,top=0; 17 long long longest_chain=0; 18 pair<int,int> longest_node; 19 void add(int x,int y,long long z) 20 { 21 node *p=&memo[top++]; 22 p->num=y; p->next=graph[x]; p->weight=z; graph[x]=p; 23 p=&memo[top++]; 24 p->num=x; p->next=graph[y]; p->weight=z; graph[y]=p; 25 } 26 void bfs(int s,long long d[]) 27 { 28 memset(father,0,sizeof(father)); 29 memset(Q,0,sizeof(Q)); 30 int left,right; 31 Q[left=right=1]=s; 32 while(left<=right) 33 { 34 int u=Q[left++]; 35 for(node *p=graph[u];p;p=p->next) 36 if(p->num!=father[u]) 37 { 38 father[p->num]=u; 39 d[p->num]=d[u]+p->weight; 40 Q[++right]=p->num; 41 } 42 } 43 } 44 void dynamic() 45 { 46 int i; 47 long long s1,s2,t1,t2; 48 for(i=n;i>0;i--) 49 { 50 t1=t2=Q[i]; 51 s1=s2=0; 52 int u=Q[i]; 53 for(node *p=graph[u];p;p=p->next) 54 if(p->num!=father[u]) 55 { 56 if(dp[p->num]+p->weight>s1) 57 { 58 s2=s1; 59 t2=t1; 60 s1=dp[p->num]+p->weight; 61 t1=path[p->num]; 62 } 63 else if(dp[p->num]+p->weight>s2) 64 { 65 s2=dp[p->num]+p->weight; 66 t2=path[p->num]; 67 } 68 } 69 dp[u]=s1; 70 path[u]=t1; 71 if(s1+s2>longest_chain) 72 { 73 longest_chain=s1+s2; 74 longest_node=make_pair(t1,t2); 75 } 76 } 77 } 78 int main() 79 { 80 int x,y,i; 81 long long z; 82 memset(graph,0,sizeof(graph)); 83 scanf("%d%d",&n,&m); 84 for(i=1;i<=m;i++) 85 { 86 scanf("%d%d%lld",&x,&y,&z); 87 add(x,y,z); 88 } 89 memset(d1,0,sizeof(d1)); 90 bfs(1,d1); 91 dynamic(); 92 memset(d1,0,sizeof(d1)); 93 memset(d2,0,sizeof(d2)); 94 bfs(longest_node.first,d1); 95 bfs(longest_node.second,d2); 96 long long ans=0; 97 for(i=1;i<=n;i++) 98 if(min(d1[i],d2[i])>ans) 99 ans=min(d1[i],d2[i]); 100 printf("%lld\n",longest_chain+ans); 101 return 0; 102 }