bzoj5152 [Wc2018]通道

题目链接

正解:不会做。

写一个爬山算法就过官方数据了(逃

具体来说就是每次随机一个根,然后迭代找最长路的那个点。

多随机几次取$max$就行了。正解以后再补。。

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 #define N (100005)
 6 
 7 using namespace std;
 8 
 9 int pos[N],vis[N],q[N],n;
10 ll dis[3][N],ans;
11 
12 il int gi(){
13   RG int x=0,q=1; RG char ch=getchar();
14   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
15   if (ch=='-') q=-1,ch=getchar();
16   while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
17   return q*x;
18 }
19 
20 struct graph{
21   
22   struct edge{ int nt,to; ll dis; }g[N<<1];
23   
24   int head[N],num;
25   
26   il void insert(RG int from,RG int to,RG ll dis){
27     g[++num]=(edge){head[from],to,dis},head[from]=num; return;
28   }
29   
30 }G[3];
31 
32 il void bfs(RG int op,RG int S){
33   for (RG int i=1;i<=n;++i) vis[i]=0;
34   RG int h=0,t=1; q[t]=S,vis[S]=1,dis[op][S]=0;
35   while (h<t){
36     RG int x=q[++h],v;
37     for (RG int i=G[op].head[x];i;i=G[op].g[i].nt){
38       v=G[op].g[i].to; if (vis[v]) continue;
39       vis[v]=1,q[++t]=v,dis[op][v]=dis[op][x]+G[op].g[i].dis;
40     }
41   }
42   return;
43 }
44 
45 int main(){
46 #ifndef ONLINE_JUDGE
47   freopen("tunnel.in","r",stdin);
48   freopen("tunnel.out","w",stdout);
49 #endif
50   srand(19260817),n=gi();
51   for (RG int i=1,u,v;i<n;++i){
52     u=gi(),v=gi(); RG ll w; scanf("%lld",&w);
53     G[0].insert(u,v,w),G[0].insert(v,u,w);
54   }
55   for (RG int i=1,u,v;i<n;++i){
56     u=gi(),v=gi(); RG ll w; scanf("%lld",&w);
57     G[1].insert(u,v,w),G[1].insert(v,u,w);
58   }
59   for (RG int i=1,u,v;i<n;++i){
60     u=gi(),v=gi(); RG ll w; scanf("%lld",&w);
61     G[2].insert(u,v,w),G[2].insert(v,u,w);
62   }
63   for (RG int i=1;i<=n;++i) pos[i]=i;
64   random_shuffle(pos+1,pos+n+1);
65   for (RG int T=1,rt;T<=25;++T){
66     rt=pos[T]; RG ll ret=0;
67     while (1){
68       bfs(0,rt),bfs(1,rt),bfs(2,rt);
69       RG ll res=0; RG int id=0;
70       for (RG int i=1;i<=n;++i)
71     if (res<dis[0][i]+dis[1][i]+dis[2][i])
72       res=dis[0][i]+dis[1][i]+dis[2][i],id=i;
73       if (ret<res) ret=res,rt=id; else break;
74     }
75     ans=max(ans,ret);
76   }
77   cout<<ans; return 0;
78 }
原文地址:https://www.cnblogs.com/wfj2048/p/8443047.html