湖南附中模拟day1 瞭望塔



/*
这个题要用到树的性质,一般比较难的图论题会往这方面靠拢,这样用很容易出错,应该先写暴力,然后再去一点点想正解
*/
//暴力70分
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
const int maxn = ;
int read(){
char ch=getchar();
int x=,f=;
while(!(ch>=''&&ch<='')){if(ch=='-')f=-;ch=getchar();};
while(ch>=''&&ch<=''){x=x*+(ch-'');ch=getchar();};
return x*f;
}
struct edge{
int v;
int w;
int nxt;
}e[maxn*];
int vis[maxn],d[maxn],flag,n,fa[maxn],tmp,ans;
int head[maxn],cnt;
vector<int> acc;
void ins(int u,int v,int w){
cnt++;
e[cnt].v = v;
e[cnt].w = w;
e[cnt].nxt = head[u];
head[u] = cnt;
}
void dfs(int u,int f){
for(int i = head[u];i;i = e[i].nxt){
if(e[i].v == f) continue;
fa[e[i].v] = u;
dfs(e[i].v,u);
}
}
void dfs2(int u){
acc.push_back(u);
for(int i = head[u];i;i = e[i].nxt){
if(e[i].v == fa[u]) continue;
dfs2(e[i].v);
}
}
void dfs3(int u,int d){
vis[u] = true;
for(int i = head[u];i;i = e[i].nxt){
if(vis[e[i].v]) continue;
dfs3(e[i].v,d+e[i].w);
}
tmp = max(tmp,d);
//cout<<tmp<<endl;
}
int get_ans(int t){
ans = ;
acc.clear();
dfs2(t);
//cout<<acc.size()<<endl;
for(int i = ;i < acc.size();i++){
tmp = ;
memset(vis,false,sizeof(vis));
vis[fa[t]] = true;
dfs3(acc[i],);
ans = min(tmp,ans);
}
return ans;
}
void baoli(){
for(int i = ;i <= n;i++){
cout<<get_ans(i)<<endl;
}
}
int main(){
freopen("tower.in","r",stdin);
freopen("tower.out","w",stdout);
n = read();
int u,v,l;
for(int i = ;i < n;i++){
u = read();
v = read();
l = read();
ins(u,v,l);
ins(v,u,l);
}
dfs(,);
baoli();
return ;
}
//正解
#include <cstdio>
#include <algorithm>
#include <cstdlib>
using namespace std; #define N 100010 int h[N], parent[N][], dmax[N], droot[N], diameter[N], radius[N], end[N];
int n, tote, height; struct edge{
int t, l, n;
}e[N * ]; void adde(int u, int v, int l) {
e[++tote].t = v;
e[tote].l = l;
e[tote].n = h[u];
h[u] = tote;
return ;
} void dfs1(int u) {
for (int i = h[u]; i; i = e[i].n) {
int v = e[i].t;
if (v == parent[u][]) continue;
parent[v][] = u;
dfs1(v);
}
return ;
} void dfs2(int u) {
int dmax2 = ;
dmax[u] = diameter[u] = radius[u] = ;//分别代表以u为根的最长路径,直径,半径
end[u] = u;//最长路径的叶子节点
for (int i = h[u]; i; i = e[i].n) {
int v = e[i].t, l = e[i].l;
if (parent[u][] == v) continue;
droot[v] = droot[u] + l;//到路径的距离
dfs2(v);//递归子节点
if (diameter[v] > diameter[u]) {//注意这里,直径有可能不经过根节点,这样半径直接用子树的
diameter[u] = diameter[v];
radius[u] = radius[v];
}
if (dmax[v] + l >= dmax[u]) {//最长路径
dmax2 = dmax[u];
dmax[u] = dmax[v] + l;
end[u] = end[v];
}
else if (dmax[v] + l > dmax2)//次长路径
dmax2 = dmax[v] + l;
if (dmax[u] + dmax2 > diameter[u]) {//直径被更新,需要更新半径
diameter[u] = dmax[u] + dmax2;
int t = height, z = end[u];
while (t >= ) {
if (parent[z][t] != && (dmax2 + droot[parent[z][t]] - droot[u]) > (dmax[u] + dmax2) / ) z = parent[z][t];//寻找一个节点,他是直径中所有子节点中,到最长路径叶子节点的长度小于他到次长路径叶子节点的长度的节点中,到前者距离最长的一个
t--;
}
int l1 = dmax2 + droot[z] - droot[u];//上面提到的到次长叶节点的路径长度
int l2 = diameter[u] - (droot[parent[z][]] - droot[u]) - dmax2;//这个点的父亲到最长叶节点的路径长度
radius[u] = min(l1, l2);//两者比较,谁更优就选谁,也就是半径长度
}
}
return ;
} int main() {
freopen("tower.in", "r", stdin);
freopen("tower.out", "w", stdout); scanf("%d",&n);
for (int i = ; i < n; i++) {
int u, v, l;
scanf("%d%d%d", &u, &v, &l);
adde(u, v, l); adde(v, u, l);
}
dfs1();//倍增处理相关
for(int i = ; i <= ; i++){
bool flag = false;
for (int j = ; j <= n; j++) {
parent[j][i] = parent[parent[j][i - ]][i - ];//找祖先
if (parent[j][i] != ) flag = true;
}
if (!flag) {
height = i;//记录高度
break;
}
}
dfs2();
for (int i = ; i <= n; i++) printf("%d\n", radius[i]); fclose(stdin);
fclose(stdout);
return ;
}
湖南附中模拟day1 瞭望塔的更多相关文章
- 湖南附中模拟day1 收银员
4.1 题意描述花花家的超市是 24 小时营业的,现在需要招聘收银员.超市每个小时都需要不同数量的收银员,用 ai 表示一天中 i 点到 i + 1 点这一小时内需要的收银员数量,特别地 a23 表示 ...
- 湖南附中模拟day1 金坷垃
题意描述"没有金坷垃,怎么种庄稼?"花花家有一块田,所有庄稼排成了 N 行 M 列.初始时,每棵庄稼都有一个自己的高度hi;j.花花每次可以使用 1mol 的金克拉使一棵庄稼的高度 ...
- 【bzoj1038】瞭望塔
[bzoj1038]瞭望塔 题意 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折 ...
- 1038: [ZJOI2008]瞭望塔
半平面交. 半平面指的就是一条直线的左面(也不知道对不对) 半平面交就是指很多半平面的公共部分. 这道题的解一定在各条直线的半平面交中. 而且瞭望塔只可能在各个点或者半平面交折线的拐点处. 求出半平面 ...
- 1038: [ZJOI2008]瞭望塔 - BZOJ
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔
1038: [ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 ...
- bzoj1038: [ZJOI2008]瞭望塔
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- BZOJ 1038 瞭望塔
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- [ZJOI2008]瞭望塔
题目描述 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安. 我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), ...
随机推荐
- 数据结构算法C语言实现(四)---2.3循环链表与双向链表
一.简述 [工作中...]
- tmux/screen里面如何用鼠标滚轮来卷动窗口内容
tmux里面用鼠标滚轮来卷动窗口内容 在 tmux里面,因为每个窗口(tmux window)的历史内容已经被tmux接管了,所以原来console/terminal提供的Shift+PgUp/PgD ...
- SublimeREPL快捷键设置
SublimeREPL 允许你在 Sublime Text 中运行各种语言(NodeJS , Python,Ruby, Scala 和 Haskell 等等).所以对于程序员来说,这是很重要的一个插件 ...
- Win10 Theano Install Guide
basic install guide 1. download miniconda 2. conda install libpython mingw 3. conda install theano n ...
- hdu 1272 小希的迷宫
小希的迷宫 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- JSF JQUERY 使用datepicker
不推荐使用.可以用primefaces的p:Calendar替代,更换控制使用. 简单使用jquery的datepicker示例: <!doctype html> <html lan ...
- Servlet3.0中Servlet的使用
目录 1.注解配置 2.异步调用 3.文件上传 相对于之前的版本,Servlet3.0中的Servlet有以下改进: l 支持注解配置. l 支持异步调用. l 直接有对文件上传的支持. 在这篇 ...
- css的核心内容 标准流、盒子模型、浮动、定位等分析
1.块级元素:如:<div></div>2.行内元素:如:<span></span>从效果中看块级元素与行内元素的区别: 通过CSS的设置把行内元素转换 ...
- css3实现小黄人
效果就像这样: 不废话,直接上代码! hrml代码: <!DOCTYPE html> <html> <head lang="zh"> <m ...
- LDA(转发)
主题模型-LDA浅析 分类: 数据挖掘 机器学习2012-09-03 14:09 24937人阅读 评论(16) 收藏 举报 文档allocationsemanticeach算法网络 上个月参加了在北 ...