题目:https://www.luogu.org/problemnew/show/P4220

http://uoj.ac/problem/347

先写了一下 n^2 和三棵树一样的情况,n^2 还写了ST表O(1)求 lca,其实做 n 遍 dfs 就好了...

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll rd()
{
ll ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
int const xn=1e5+;
int n,hd[][xn],ct[],to[][xn<<],nxt[][xn<<],in[][xn],st[][xn<<][],id[][xn<<][],bin[],bit[xn],tim[],dep[][xn];
ll w[][xn<<],dis[][xn];
ll Min(ll x,ll y){return x<y?x:y;}
ll Max(ll x,ll y){return x>y?x:y;}
void add(int t,int x,int y,ll z){to[t][++ct[t]]=y; nxt[t][ct[t]]=hd[t][x]; hd[t][x]=ct[t]; w[t][ct[t]]=z;}
void dfs(int t,int x,int fa)
{
in[t][x]=++tim[t]; id[t][tim[t]][]=x;
dep[t][x]=dep[t][fa]+; st[t][tim[t]][]=dep[t][x];
for(int i=hd[t][x],u;i;i=nxt[t][i])
{
if((u=to[t][i])==fa)continue;
dis[t][u]=dis[t][x]+w[t][i];
dfs(t,u,x);
st[t][++tim[t]][]=dep[t][x]; id[t][tim[t]][]=x;
}
}
void work(int t)
{
for(int i=;i<;i++)
for(int j=;j<=tim[t]&&j+bin[i]-<=tim[t];j++)
{
if(st[t][j][i-]<st[t][j+bin[i-]][i-])
st[t][j][i]=st[t][j][i-],id[t][j][i]=id[t][j][i-];
else st[t][j][i]=st[t][j+bin[i-]][i-],id[t][j][i]=id[t][j+bin[i-]][i-];
}
}
int lca(int t,int x,int y)
{
int l=in[t][x],r=in[t][y];
if(l>r)swap(l,r); int d=bit[r-l+];
if(st[t][l][d]<st[t][r-bin[d]+][d])return id[t][l][d];
return id[t][r-bin[d]+][d];
}
ll dist(int t,int x,int y){return dis[t][x]+dis[t][y]-*dis[t][lca(t,x,y)];}
void work1()
{
for(int t=;t<;t++)dfs(t,,),work(t);
ll ans=;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
ans=Max(ans,dist(,i,j)+dist(,i,j)+dist(,i,j));
printf("%lld\n",ans);
}
ll ans=;
ll dfsx(int x,int fa)
{
ll mx=,nmx=;
for(int i=hd[][x],u;i;i=nxt[][i])
{
if((u=to[][i])==fa)continue;
ll tmp=dfsx(u,x);
if(tmp+w[][i]>mx)nmx=mx,mx=tmp+w[][i];
else if(tmp+w[][i]>nmx)nmx=tmp+w[][i];
}
ans=Max(ans,mx+nmx); return mx;
}
int main()
{
n=rd(); ll z;
bin[]=; for(int i=;i<;i++)bin[i]=bin[i-]*;
bit[]=; for(int i=;i<xn;i++)bit[i]=bit[i>>]+;//not n!
for(int t=;t<;t++)
for(int i=,x,y;i<n;i++)
x=rd(),y=rd(),z=rd(),add(t,x,y,z),add(t,y,x,z);
if(n<=){work1(); return ;}
dfsx(,); printf("%lld\n",ans*);
return ;
}

44分

然后就用了随机化算法,用 clock() 和 CLOCKS_PER_SEC 卡时间,过了官方数据。

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
typedef long long ll;
ll rd()
{
ll ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
ll Min(ll x,ll y){return x<y?x:y;}
ll Max(ll x,ll y){return x>y?x:y;}
int const xn=1e5+;
int n,hd[][xn],ct[],to[][xn<<],nxt[][xn<<];
ll w[][xn<<],dis[][xn];
void add(int t,int x,int y,ll z){to[t][++ct[t]]=y; nxt[t][ct[t]]=hd[t][x]; hd[t][x]=ct[t]; w[t][ct[t]]=z;}
void dfs(int t,int x,int fa)
{
for(int i=hd[t][x],u;i;i=nxt[t][i])
if((u=to[t][i])!=fa)dis[t][u]=dis[t][x]+w[t][i],dfs(t,u,x);
}
void work1()
{
ll ans=;
for(int i=;i<=n;i++)
{
dis[][i]=dis[][i]=dis[][i]=;
for(int t=;t<;t++)dfs(t,i,);
for(int j=;j<=n;j++)ans=Max(ans,dis[][j]+dis[][j]+dis[][j]);
}
printf("%lld\n",ans);
}
bool vis[xn];
int clk(){return (double)clock()/CLOCKS_PER_SEC*;}
int main()
{
int st=clk();
n=rd(); ll z;
for(int t=;t<;t++)
for(int i=,x,y;i<n;i++)
x=rd(),y=rd(),z=rd(),add(t,x,y,z),add(t,y,x,z);
if(n<=){work1(); return ;}
srand(time()); srand(rand());
ll ans=;
for(int rt;clk()-st<=;)
{
rt=rand()%n+;
if(vis[rt])continue; vis[rt]=;
int cnt=;
while(cnt--)
{
vis[rt]=;
for(int t=;t<;t++)dis[t][rt]=,dfs(t,rt,);
ll mx=; int id=rt;
for(int i=;i<=n;i++)
{
ll tmp=dis[][i]+dis[][i]+dis[][i];
if(mx<tmp)mx=tmp;
if(!vis[i]&&dis[][id]+dis[][id]+dis[][id]<tmp)id=i;
}
ans=Max(ans,mx); if(id==rt)break; rt=id;
}
}
printf("%lld\n",ans);
return ;
}

洛谷 P4220 & UOJ #347 通道 —— 随机化的更多相关文章

  1. 洛谷 P2503 [HAOI2006]均分数据 随机化贪心

    洛谷P2503 [HAOI2006]均分数据(随机化贪心) 现在来看这个题就是水题,但模拟赛时想了1个小时贪心,推了一堆结论,最后发现贪心做 不了, 又想了半个小时dp 发现dp好像也做不了,在随机化 ...

  2. 洛谷P4220 [WC2018]通道(边分治+虚树)

    题面 传送门 题解 代码不就百来行么也不算很长丫 虽然这题随机化贪心就可以过而且速度和正解差不多不过我们还是要好好学正解 前置芝士 边分治 米娜应该都知道点分治是个什么东西,而边分治,顾名思义就是对边 ...

  3. 洛谷P3688/uoj#291. [ZJOI2017]树状数组

    传送门(uoj) 传送门(洛谷) 这里是题解以及我的卡常数历程 话说后面那几组数据莫不是lxl出的这么毒 首先不难发现这个东西把查询前缀和变成了查询后缀和,结果就是查了\([l-1,r-1]\)的区间 ...

  4. BZOJ3675 & 洛谷3648 & UOJ104:[Apio2014]序列分割——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3675 https://www.luogu.org/problemnew/show/P3648 ht ...

  5. uoj#348/洛谷P4221 [WC2018]州区划分(FWT)

    传送门(uoj) 传送门(洛谷) 全世界都会子集卷积就咱不会--全世界都在写\(FMT\)就咱只会\(FWT\)-- 前置芝士 或运算\(FWT\)或者\(FMT\) 左转洛谷模板区,包教包会 子集卷 ...

  6. 洛谷 P2827 BZOJ 4721 UOJ #264 蚯蚓

    题目描述 本题中,我们将用符号表示对c向下取整,例如:. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓. 蛐蛐国里现在共有n只蚯蚓(n为正整数).每只 ...

  7. 洛谷 P7450 - [THUSCH2017] 巧克力(斯坦纳树+随机化)

    洛谷题面传送门 9.13 补之前 8.23 做的题,不愧是鸽子 tzc( 首先我们先来探讨一下如果 \(c_{i,j}\le k\) 怎么做,先考虑第一问.显然一个连通块符合条件当且仅当它能够包含所有 ...

  8. 洛谷 P1224 - [NOI2013] 向量内积(随机化)

    洛谷题面传送门 一道很神的随机化. 首先由于我们要求向量点乘 \(\bmod k\) 的值,因此我们可以将所有 \(x_{i,j}\) 都模上 \(k\),显然该操作不影响结果正确性. 注意到这里的 ...

  9. 洛谷P2179 骑行川藏

    什么毒瘤... 解:n = 1的,发现就是一个二次函数,解出来一个v的取值范围,选最大的即可. n = 2的,猜测可以三分.于是先二分给第一段路多少能量,然后用上面的方法求第二段路的最短时间.注意剩余 ...

随机推荐

  1. Webpack探索【3】--- loader详解

    本文主要说明Webpack的loader相关内容.

  2. ORM性能相关

    model: 先给一个简单的表结构 from django.db import models class User(models.Model): username=models.CharField(m ...

  3. LeetCode:有效三角形的个数【611】

    LeetCode:有效三角形的个数[611] 题目描述 给定一个包含非负整数的数组,你的任务是统计其中可以组成三角形三条边的三元组个数. 示例 1: 输入: [2,2,3,4] 输出: 3 解释: 有 ...

  4. SpringBoot学习笔记(4):添加自定义的过滤器

    SpringBoot:学习笔记(4)——添加自定义的过滤器 引入自定义过滤器 SpringBoot提供的前端控制器无法满足我们产品的需求时,我们需要添加自定义的过滤器. SpringBoot添加过滤器 ...

  5. 项目中对模板和js,css文件进行压缩的处理类

    我们知道,在html的页面中,所有空格和换行符其实都会占据一定的空间,即使使用了gzip压缩,在传输过程中依然会浪费用户的流量和我们自己服务器的带宽,此脚本就是为了解决这个问题而诞生的. 请自行下载G ...

  6. MVC ViewBag不能使用在工程文件中添加引用

    在工程文件中 <ItemGroup> // ... </ItemGroup> 添加引用 <Reference Include="Microsoft.CSharp ...

  7. c++之helloworld与命名空间

    首先在linux中需要安装g++编译器. 在中端输入 uname -a,可以查看版本信息. 输入g++,如果提示错误.则需要使用sudo apt-get install g++. #include&l ...

  8. 【转】.net中快捷键的使用

    当前行行首:Home 当前行行尾:End 当前文档首行:ctrl+Home 当前文档尾行:ctrl+End 选中当前行: ① 按Home(定位到行首)然后按Shift+Dnd(行尾)   {从行首连选 ...

  9. 【leetcode刷题笔记】Add Binary

    Given two binary strings, return their sum (also a binary string). For example,a = "11"b = ...

  10. 【leetcode刷题笔记】Linked List Cycle

    Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ext ...