题解 P4220 【[WC2018]通道】
人生第一道非恶评黑啊qwq
核心思想就是贪心(带一点随机)
考虑一个贪心,我们现在有一个根,显然我们想找到一个点使得两者间的三条路径长度之和最大。
但是由此产生了一个问题,我们并不知道答案中的根是哪个,所以我们有一个想法就是用这个新点来继承原来的根。
然后呢?然后就没了。
是的,接下来就不断迭代然后更新最大值就完事了。
需要注意到的是这个新点有可能以前已经被计算过了,会死循环,因此记录一个vis数组判断有没有被访问,如果被访问过了,就随机出一个没有被访问过的点。
但是关键在于我们要随机多少次呢?如何既保证正确,又保证不超时呢?我们需要一个自适应的东西。
因此我们可以使用时间函数,通过 (double)clock()/CLOCKS_PER_SEC来获取程序已经运行过的时间
控制它在
上代码qwq:
#include<bits/stdc++.h>
using namespace std;
#define _ 0
#define timeused() (double)clock()/CLOCKS_PER_SEC
#define Set(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(register int i=a,i##end=b;i<=i##end;++i)
#define repp(i,a,b) for(register int i=a,i##end=b;i>=i##end;--i)
#define debug() assert(0)
typedef long long ll;
typedef unsigned long long ull;
template<typename T> inline T rd(T& x){
T f=1;x=0;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(T)(c-'0');
x*=f;
return x;
}
ll rd(){ll x;rd(x);return x;}
ll n,u,v,w,nowrt=1,maxx,dep1[100005],dep2[100005],dep3[100005],ans;
bool vis[100005];
vector<pair<ll,ll> > e1[100005],e2[100005],e3[100005];
void dfs1(ll dep,ll fa){
rep(i,0,e1[dep].size()-1){
if(e1[dep][i].first!=fa){
dep1[e1[dep][i].first]=dep1[dep]+e1[dep][i].second;
dfs1(e1[dep][i].first,dep);
}
}
}
void dfs2(ll dep,ll fa){
rep(i,0,e2[dep].size()-1){
if(e2[dep][i].first!=fa){
dep2[e2[dep][i].first]=dep2[dep]+e2[dep][i].second;
dfs2(e2[dep][i].first,dep);
}
}
}
void dfs3(ll dep,ll fa){
rep(i,0,e3[dep].size()-1){
if(e3[dep][i].first!=fa){
dep3[e3[dep][i].first]=dep3[dep]+e3[dep][i].second;
dfs3(e3[dep][i].first,dep);
}
}
}
int main(){
n=rd();
rep(i,1,n-1){
u=rd();
v=rd();
w=rd();
e1[u].push_back(make_pair(v,w));
e1[v].push_back(make_pair(u,w));
}
rep(i,1,n-1){
u=rd();
v=rd();
w=rd();
e2[u].push_back(make_pair(v,w));
e2[v].push_back(make_pair(u,w));
}
rep(i,1,n-1){
u=rd();
v=rd();
w=rd();
e3[u].push_back(make_pair(v,w));
e3[v].push_back(make_pair(u,w));
}
while(timeused()<3.85){
while(vis[nowrt]&&timeused()<3.85) nowrt=rand()%n+1;
vis[nowrt]=1;
dep1[nowrt]=dep2[nowrt]=dep3[nowrt]=0;
dfs1(nowrt,0);
dfs2(nowrt,0);
dfs3(nowrt,0);
maxx=0;
rep(i,1,n){
if(dep1[i]+dep2[i]+dep3[i]>maxx){
maxx=dep1[i]+dep2[i]+dep3[i];
nowrt=i;
}
}
ans=max(ans,maxx);
}
printf("%lld",ans);
return ~~(0^_^0);
}