大意: 给定一个基环树, 求删除一条环上的边使得直径最小.

直径分两种情况

  • 环上点延伸的树内的直径
  • 两个环上点的树内深度最大的点匹配

第一种情况直接树形dp求一下, 第二种情况枚举删除的环边, 线段树维护一下即可.

#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <cstring>
#include <bitset>
#include <functional>
#include <random>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
#define DB(a) ({REP(__i,1,n) cout<<a[__i]<<',';hr;})
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
//head const int N = 1e6+10;
int n,dep[N],vis[N];
struct _ {int to,w;} fa[N];
vector<_> g[N];
int a[N], v[N], top;
ll mx[N], b[N], sum[N], ans, ans2;
struct node {
ll m1,m2,v;
node operator + (const node &rhs) const {
node ret;
ret.m1=max(m1,rhs.m1);
ret.m2=max(m2,rhs.m2);
ret.v=max(v,rhs.v);
ret.v=max(ret.v,m2+rhs.m1);
return ret;
}
} tr[N<<2]; void get(int x, int y) {
if (dep[x]<dep[y]) return;
v[++top] = y;
a[top+1] = fa[y].w;
for (; x!=y; x=fa[x].to) v[++top] = x, a[top+1] = fa[x].w;
}
void dfs(int x, int f) {
dep[x] = dep[f]+1;
for (_ e:g[x]) if (e.to!=f) {
int y = e.to;
fa[y] = {x,e.w};
if (dep[y]) get(x,y);
else dfs(y,x);
}
}
void dfs2(int x) {
vis[x] = 1;
for (_ e:g[x]) if (!vis[e.to]) {
int y = e.to;
dfs2(y);
ans = max(ans, mx[x]+mx[y]+e.w);
mx[x] = max(mx[x], mx[y]+e.w);
}
} void build(int o, int l, int r) {
if (l==r) tr[o].m1=b[l]+sum[l],tr[o].m2=b[l]-sum[l],tr[o].v=0;
else {
build(ls),build(rs);
tr[o]=tr[lc]+tr[rc];
}
}
node qry(int o, int l, int r, int ql, int qr) {
if (ql<=l&&r<=qr) return tr[o];
if (mid>=qr) return qry(ls,ql,qr);
if (mid<ql) return qry(rs,ql,qr);
return qry(ls,ql,qr)+qry(rs,ql,qr);
} int main() {
scanf("%d", &n);
REP(i,1,n) {
int u, v, w;
scanf("%d%d%d",&u,&v,&w);
g[u].pb({v,w});
g[v].pb({u,w});
}
dfs(1,0);
REP(i,1,top) vis[v[i]]=1;
REP(i,1,top) dfs2(v[i]),b[i]=mx[v[i]];
REP(i,top+1,2*top-1) b[i] = b[i-top];
REP(i,top+2,2*top-1) a[i] = a[i-top];
REP(i,1,2*top-1) sum[i] = sum[i-1]+a[i];
build(1,1,2*top-1);
ans2 = 1e18;
REP(i,1,top) ans2 = min(ans2, qry(1,1,2*top-1,i,i+top-1).v);
printf("%lld\n",max(ans,ans2));
}

Roads in the Kingdom CodeForces - 835F (直径)的更多相关文章

  1. Codeforces 835F Roads in the Kingdom (环套树 + DP)

    题目链接 Roads in the Kingdom 题意  给出一个环套树的结构,现在要删去这个结构中的一条边,满足所有点依然连通. 删边之后的这个结构是一棵树,求所有删边情况中树的直径的最小值. 显 ...

  2. Codeforces 835 F. Roads in the Kingdom

    \(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...

  3. Codeforces 835 F Roads in the Kingdom(树形dp)

    F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...

  4. codeforces 427 div.2 F. Roads in the Kingdom

    F. Roads in the Kingdom time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  5. POJ 2631 Roads in the North(树的直径)

    POJ 2631 Roads in the North(树的直径) http://poj.org/problem? id=2631 题意: 有一个树结构, 给你树的全部边(u,v,cost), 表示u ...

  6. Codeforces 835F Roads in the Kingdom - 动态规划

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一颗基环树,要求删去其中一条边,使得剩下的图形是一棵树,并且最长路的长度最短,求最长路的最短长度. 路径可以分为两部分:跨过环 和 在树内 ...

  7. 【CodeForces】835F Roads in the Kingdom

    一.题目 题目描述 王国有\(n\)座城市与\(n\)条有长度的街道,保证所有城市直接或间接联通,我们定义王国的直径为所有点对最短距离中的最大值,现因财政危机需拆除一条道路并同时要求所有城市仍然联通, ...

  8. Codeforces 1413F - Roads and Ramen(树的直径+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 其实是一道还算一般的题罢--大概是最近刷长链剖分,被某道长链剖分与直径结合的题爆踩之后就点开了这题. 本题的难点就在于看出一个性质:最长路 ...

  9. CF835F Roads in the Kingdom/UOJ126 NOI2013 快餐店 树的直径

    传送门--CF 传送门--UOJ 题目要求基环树删掉环上的一条边得到的树的直径的最小值. 如果直接考虑删哪条边最优似乎不太可做,于是考虑另一种想法:枚举删掉的边并快速地求出当前的直径. 对于环上的点, ...

随机推荐

  1. USACO 奶牛抗议 Generic Cow Protests

    USACO 奶牛抗议 Generic Cow Protests Description 约翰家的N头奶牛聚集在一起,排成一列,正在进行一项抗议活动.第i头奶牛的理智度 为Ai,Ai可能是负数.约翰希望 ...

  2. MongoDB 索引 和 explain 的使用

    索引基本使用 索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得 更快.MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查 询优化技巧. 首先我 ...

  3. Java_jdbc 基础笔记之十三 数据库连接(DAO)

    public class DAO { // INSERT, UPDATE, DELETE 操作都可以包含在其中 public void update(String sql, Object... arg ...

  4. flask 实现最简单的登录功能

    视图函数如下: # Sample.py from flask import Flask, render_template, url_for, request, redirect app = Flask ...

  5. 解决iis内存占用过大的问题--ZT

    解决iis内存占用过大的问题 在IIS6下,经常出现w3wp的内存占用不能及时释放,从而导致服务器响应速度很慢. 今天研究了一下,可以做以下配置: 1.在IIS中对每个网站进行单独的应用程序池配置.即 ...

  6. cas 3.5.3服务器搭建+spring boot集成+shiro模拟登录(不修改现有shiro认证架构)

    因为现有系统外部接入需要,需要支持三方单点登录.由于系统本身已经是微服务架构,由多个业务独立的子系统组成,所以有自己的用户认证微服务(不是cas,我们基础设施已经够多了,现在能不增加就不增加).但是因 ...

  7. nginx日志切割和日志清理

    ##########################日志切割################################1.上传脚本到/usr/local/nginx/logs/下 2.并附执行权 ...

  8. Python之schedule用法,类似linux下的crontab

    # -*- coding: utf-8 -*- # author:baoshan import schedule import time def job(): print("I'm work ...

  9. Python3 多线程(连接池)操作MySQL插入数据

    1.主要模块DBUtils : 允许在多线程应用和数据库之间连接的模块套件Threading : 提供多线程功能 2.创建连接池PooledDB 基本参数: mincached : 最少的空闲连接数, ...

  10. tomcat乱码解决

    一.修改Tomcat的conf的server.xml文件加上 URIEncoding="UTF-8" 二.在tomcat的bin 目录下的catalina.bat 配置文件中,添加 ...