湖南附中模拟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), ...
随机推荐
- [iOS OpenCV的使用,灰度和二值化]
看网上方法很多,但版本都不够新,我看了网上一些知识,总结了下,来个最新版Xcode6.1的. 最近主要想做iOS端的车牌识别,所以开始了解OpenCV.有兴趣的可以跟我交流下哈. 一.Opencv的使 ...
- JAva使用DOM读取XML数据(解析)
原来一切都是有套路的 使用DOM解析XML文档步骤 1.创建解析器工厂对象 DocumentBuildFactory对象 2.由解析器工厂对象创建解析器对象,即DocumentBuilder对象 3. ...
- hdu 2036 - 改革春风吹满地(计算几何)
题意:求解多边形面积 解法: 先了解数学上"叉积"的含义与性质: 三角形ΔABC的面积为: 我们可以依次计算每个三角形的面积,ΔABC,ΔACE,ΔEF - - 所有三角形的面积之 ...
- 捉襟见肘之UITableViewCell重用引发的问题
我记录一下自己如何解决cell内容重叠的问题 首先,复习一下:http://blog.csdn.net/omegayy/article/details/7356823 UITableViewCell的 ...
- 高可用与负载均衡(1)之linux系统的数据链路层负载均衡
preface 在蓝厂就职到时候,每台缓存服务器都能够跑到2G的流量,这么大的流量,有人会问,服务器是不是安装的万兆网卡,no no no,仅仅是3张千兆网卡绑定在一块.万兆网卡的服务器少见,大多数都 ...
- R in bioinformatic
TCGA https://www.bioconductor.org/packages/release/bioc/vignettes/TCGAbiolinks/inst/doc/tcgaBiolinks ...
- c#.net WinForm 线程内 调用窗体控件
richTextBox1.BeginInvoke(new EventHandler(delegate { richTextBox1.AppendText("正在提交服务器..\r\n&quo ...
- 才知道创建数据表的后面int(M)的m居然和存储大小没有关系
之前一直以为,后面m代表有几个字节 MySQL 数据类型中的 integer types 有点奇怪.你可能会见到诸如:int(3).int(4).int(8) 之类的 int 数据类型.刚接触 MyS ...
- 自然语言16.1_Python自然语言处理学习笔记之信息提取步骤&分块(chunking)
QQ:231469242 欢迎喜欢nltk朋友交流 http://www.cnblogs.com/undercurrent/p/4754944.html 一.信息提取模型 信息提取的步骤共分为五步,原 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【十】——使用CacheCow和ETag缓存资源
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的 ...