[SDOI2013]直径 (树的直径,贪心)
题目链接
Solution
我们直接找到一条直径 \(s\),起点为 \(begin\),终点为 \(end\).
从前往后遍历点 \(u\) ,若子树中最大的距离与 \(dis(u,begin)\) 相等.
很显然这个点不在公共线段上,很显然可以用子树的中的一段接上,形成一条新的直径.
然后从后往前遍历,同样的道理...
然后找到两个节点 \(l,r\) 然后答案即为 \(r-l\).
记得要开 \(longlong\).
Code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=300008;
struct sj{
ll to,next,w;
}a[maxn*2];
ll head[maxn],size;
ll n,s,x,y,w;
ll read()
{
ll f=1,w=0; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){w=w*10+ch-'0';ch=getchar();}
return f*w;
}
void add(ll x,ll y,ll w)
{
a[++size].to=y;
a[size].next=head[x];
head[x]=size;a[size].w=w;
}
ll last,num,now,cnt,v[maxn],bcnt;
ll ans[maxn],maxx,road[maxn];
ll dist[maxn],b[maxn],ansb[maxn];
ll sum[maxn];
void dfs(ll x)
{
v[x]=1;
road[++cnt]=x;
for(ll i=head[x];i;i=a[i].next)
{
ll tt=a[i].to;
if(!v[tt])
{
now+=a[i].w;
b[++bcnt]=a[i].w;
dfs(tt); cnt--;bcnt--;
now-=a[i].w;
}
}
if(now>maxx)
{
num=cnt; last=x; maxx=now;
for(ll i=1;i<=cnt;i++)
ans[i]=road[i],ansb[i]=b[i];
}
}
void getdist(ll x)
{
v[x]=1;
maxx=max(maxx,now);
for(ll i=head[x];i;i=a[i].next)
{
ll tt=a[i].to;
if(!v[tt])
{
now+=a[i].w;
getdist(tt);
now-=a[i].w;
}
}
}
int main()
{
n=read();
for(ll i=1;i<n;i++)
{
x=read(); y=read(); w=read();
add(x,y,w); add(y,x,w);
}
dfs(1);
memset(v,0,sizeof(v));
maxx=0; cnt=0; now=0;
dfs(last);
memset(v,0,sizeof(v));
for(ll i=1;i<=num;i++)v[ans[i]]=1;
for(ll i=2;i<=num;i++)sum[i]=sum[i-1]+ansb[i-1];
for(ll i=1;i<=num;i++)
{maxx=0,getdist(ans[i]),dist[i]=maxx;}
ll l=1,r=num;
for(int i=1;i<=num;i++)
if(sum[i]==dist[i]) l=i;
for(int i=num;i>=1;i--)
if(sum[num]-sum[i]==dist[i]) r=i;
cout<<sum[num]<<endl;
cout<<r-l<<endl;
}
[SDOI2013]直径 (树的直径,贪心)的更多相关文章
- POJ 1985.Cow Marathon-树的直径-树的直径模板(BFS、DFS(vector存图)、DFS(前向星存图))
Cow Marathon Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 7536 Accepted: 3559 Case ...
- 树形DP 学习笔记(树形DP、树的直径、树的重心)
前言:寒假讲过树形DP,这次再复习一下. -------------- 基本的树形DP 实现形式 树形DP的主要实现形式是$dfs$.这是因为树的特殊结构决定的——只有确定了儿子,才能决定父亲.划分阶 ...
- Sonya and Ice Cream CodeForces - 1004E 树的直径, 贪心
题目链接 set维护最小值贪心, 刚开始用树的直径+单调队列没调出来... #include <iostream>#include <cstdio> #include < ...
- [NOI2003]逃学的小孩 (贪心+树的直径+暴力枚举)
Input 第一行是两个整数N(3 <= N <= 200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的信息.第i+1行包含整数Ui.Vi.Ti(1<=Ui ...
- SDOI2013直径(树的直径)
题目描述: 点这里 题目大意: 就是在一个树上找其直径的长度是多少,以及有多少条边满足所有的直径都经过该边. 题解: 首先,第一问很好求,两边dfs就行了,第一次从任一点找距它最远的点,再从这个点找距 ...
- [TJOI2017] 城市 (树的直径,贪心)
题目链接 Solution 这道题,调了我一晚上... 一直80分 >_<|| ... 考虑到几点: 分开任意一条边 \(u\) ,那么其肯定会断成两棵树. 肯定是分开直径上的边最优,否则 ...
- BZOJ3124 [Sdoi2013]直径 【树的直径】
题目 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一棵树上,任意两个节 ...
- CF911F Tree Destruction (树的直径,贪心)
题目链接 Solution 1.先找出树的直径. 2.遍历直径沿途的每一个节点以及它的子树. 3.然后对于每个非直径节点直接统计答案,令直径的两个端点为 \(x_1,x_2\) . \[Ans=\su ...
- 与图论的邂逅01:树的直径&基环树&单调队列
树的直径 定义:树中最远的两个节点之间的距离被称为树的直径. 怎么求呢?有两种官方的算法(不要问官方指谁我也不晓得): 1.两次搜索.首先任选一个点,从它开始搜索,找到离它最远的节点x.然后从x开始 ...
随机推荐
- 连接惠普打印机(通过WIFI)
第一步 找到打印机型号 第二步 到惠普官方网站下载对应驱动 第三步 安装驱动 第四步 安装驱动后选择WIFI连接(IP在打印机显示屏幕上显示,如果输入打印机屏幕IP连接失败:需要获取打印机真正的IP地 ...
- 用 label 控制 Pod 的位置
默认配置下,Scheduler 会将 Pod 调度到所有可用的 Node.不过有些情况我们希望将 Pod 部署到指定的 Node,比如将有大量磁盘 I/O 的 Pod 部署到配置了 SSD 的 Nod ...
- windbg双机调试配置
环境 虚拟机 win7 Pro x86 vmware 12 windbg x86 虚拟机win7配置 管理员权限运行cmd.exe 然后输入以下命令: bcdedit /? bcdedit /enum ...
- (转发)IOS高级开发~Runtime(三)
11.系统类的方法实现部分替换 - (void) methodExchange { Method m1 = class_getInstanceMethod([NSStringclass],@selec ...
- 【思维题】TCO14 Round 2C InverseRMQ
全网好像就只有劼和manchery写了博客的样子……:正解可能是最大流?但是仔细特判也能过 题目描述 RMQ问题即区间最值问题是一个有趣的问题. 在这个问题中,对于一个长度为 n 的排列,query( ...
- [BZOJ] 4145: [AMPPZ2014]The Prices
设\(f[S][i]\)表示考虑到第\(i\)家店,已经买了集合\(S\)内的物品 一个朴素的想法是枚举子集转移 \[ f[S][i]=\min\{f[T][i-1]+cost[S\oplus T][ ...
- [51nod] 1301 集合异或和
考虑不限制xor{Y}>xor{X} 考虑n=m的情况,每个数i∈[1,n]可以被分配到X集合或Y集合,或不分配 设f[S]表示{X} xor {Y} == S的方案数 有f[S]+=2*f[S ...
- percona-toolkit工具使用介绍
percona-toolkit工具使用介绍 1. pt-heartbeat 1.1 pt-heartbeat 原理 1.2 pt-heartbeat 主要参数介绍 1.3 pt-heartbeat 实 ...
- CentOS 7 忘记root密码解决方法
CentOS 7 root密码的重置方式和CentOS 6完全不一样,CentOS 7与之前的版本6变化还是比较大的,以进入单用户模式修改root密码为例: 1.重启机器,进入grub菜单的时候按e ...
- ubuntu中卸载没有安装完全的软件包
sudo apt-get autoclean sudo apt-get clean sudo apt-get autoremove