[Sdoi2013]直径(树的直径)
//36分
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll; #define setfire(name) freopen(#name".in","r",stdin);freopen(#name".out","w",stdout);
#define fre(name) freopen(#name".txt","r",stdin);
#ifdef WIN32
#define LL "%lld"
#else
#define LL "%I64d"
#endif const int N=2e5+;
const int Z=;
int n,S1,S2,la,lb,s_cnt,b[N],stack[N],prev[N];char s[];bool vis[N];
struct edge{int u,v,next;ll w;}e[N<<];int tot=,head[N];
int dep[N],fa[N][];
ll ans,LEN,dis[N],dist[N];
bool mark[Z][Z];
struct data{int x,y;}state[N];
inline int read(){
int x=;char ch=getchar();
while(ch<''||ch>''){ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x;
}
inline void add(int x,int y,int z){
e[++tot].u=x;e[tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
e[++tot].u=y;e[tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;
}
void BFS(int S){
int top=;
stack[top]=S;dep[S]=;fa[S][]=S;
while(top){
int x=stack[top--];
for(int i=head[x];i;i=e[i].next){
if(e[i].v!=fa[x][]){
fa[e[i].v][]=x;
dep[e[i].v]=dep[x]+;
dist[e[i].v]=dist[x]+e[i].w;
stack[++top]=e[i].v;
}
}
}
}
inline int bfs(int S){
memset(dis,-,sizeof dis);
memset(vis,,sizeof vis);
int id=,mx=-,top=;
stack[top]=S;dis[S]=;vis[S]=;
while(top){
int x=stack[top--];
for(int i=head[x];i;i=e[i].next){
if(!vis[e[i].v]&&dis[e[i].v]<dis[x]+e[i].w){
vis[e[i].v]=;
dis[e[i].v]=dis[x]+e[i].w;
if(dis[e[i].v]>mx) mx=dis[e[i].v],id=e[i].v;
stack[++top]=e[i].v;
}
}
}
return id;
}
void gosolve(int S,int T){
memset(vis,,sizeof vis);
int id=,mx=-,top=;
stack[top]=S;vis[S]=;
while(top){
int x=stack[top--];
for(int i=head[x];i;i=e[i].next){
if(!vis[e[i].v]){
vis[e[i].v]=;
prev[e[i].v]=i;
if(e[i].v==T){top=;break;}
stack[++top]=e[i].v;
}
}
}
for(int i=T;i!=S;i=e[prev[i]^].v) b[prev[i]>>]++;
}
int lca(int a,int b){
if(dep[a]<dep[b]) swap(a,b);
int t=dep[a]-dep[b];
for(int i=;i<=;i++){
if(t&(<<i)){
a=fa[a][i];
}
}
if(a==b) return a;
for(int i=;i>=;i--){
if(fa[a][i]!=fa[b][i]){
a=fa[a][i];
b=fa[b][i];
}
}
return fa[a][];
}
void init(){
n=read();
for(int i=,x,y,z;i<n;i++) x=read(),y=read(),z=read(),add(x,y,z);
}
void dp_tree_len(int x,int fa){
for(int i=head[x],y;i;i=e[i].next){
if((y=e[i].v)!=fa){
if((x==la&&y==lb)||(x==lb&&y==la)) continue;
dp_tree_len(y,x);
LEN=max(LEN,dis[x]+dis[y]+e[i].w);
dis[x]=max(dis[x],dis[y]+e[i].w);
}
}
}
void work(){
if(n<=){
BFS();
for(int i=,mx=;i<=n;i++) if(dist[i]>mx) mx=dist[i],S1=i;
S2=bfs(S1);
LEN=dis[S2];
printf("%I64d\n",LEN);
for(int j=;j<=;j++){
for(int i=;i<=n;i++){
fa[i][j]=fa[fa[i][j-]][j-];
}
}
ll lt;
for(int i=,anc;i<=n;i++){
for(int j=;j<i;j++){
if(mark[i][j]) continue;
anc=lca(i,j);
lt=dist[i]+dist[j]-dist[anc]*;
if(lt==LEN) mark[i][j]=,state[++s_cnt]=(data){i,j};
}
}
//直径条数
for(int i=;i<=s_cnt;i++){
gosolve(state[i].x,state[i].y);
}
int num=;
for(int i=;i<=n;i++) if(b[i]==s_cnt) num++;
printf("%d",num);
}
else{
dp_tree_len(,);
printf("%I64d\n",LEN);
}
}
int main(){
freopen("diameter.in","r",stdin);
freopen("diameter.out","w",stdout);
int size=<<;
char *p=(char*)malloc(size)+size;
__asm__("movl %0,%%esp\n"::"r"(p));
init();
work();
return ;
}
[Sdoi2013]直径(树的直径)的更多相关文章
- POJ 1985.Cow Marathon-树的直径-树的直径模板(BFS、DFS(vector存图)、DFS(前向星存图))
Cow Marathon Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 7536 Accepted: 3559 Case ...
- [SDOI2013]直径 (树的直径,贪心)
题目链接 Solution 我们直接找到一条直径 \(s\),起点为 \(begin\),终点为 \(end\). 从前往后遍历点 \(u\) ,若子树中最大的距离与 \(dis(u,begin)\) ...
- 树形DP 学习笔记(树形DP、树的直径、树的重心)
前言:寒假讲过树形DP,这次再复习一下. -------------- 基本的树形DP 实现形式 树形DP的主要实现形式是$dfs$.这是因为树的特殊结构决定的——只有确定了儿子,才能决定父亲.划分阶 ...
- SDOI2013直径(树的直径)
题目描述: 点这里 题目大意: 就是在一个树上找其直径的长度是多少,以及有多少条边满足所有的直径都经过该边. 题解: 首先,第一问很好求,两边dfs就行了,第一次从任一点找距它最远的点,再从这个点找距 ...
- BZOJ3124 [Sdoi2013]直径 【树的直径】
题目 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一棵树上,任意两个节 ...
- poj2631 求树的直径裸题
题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: ...
- poj1985 Cow Marathon (求树的直径)
Cow Marathon Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 3195 Accepted: 1596 Case ...
- VIJOS1476旅游规划[树形DP 树的直径]
描述 W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流.但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员.具体说来,W市的交通网络十分简单,它包 ...
- poj2631 树的直径
设s-t是这棵树的直径,那么对于任意给予的一点,它能够到达的最远的点是s或者t. 这样我们可以通过2次bfs找到树的直径了. #include<cstdio> #include<qu ...
- 【BZOJ-1912】patrol巡逻 树的直径 + DFS(树形DP)
1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1034 Solved: 562[Submit][St ...
随机推荐
- 五个常用的Linux监控脚本代码
bash中 2>&1 & 的解释 1.首先,bash中0,1,2三个数字分别代表STDIN_FILENO.STDOUT_FILENO.STDERR_FILENO,即标准输入(一般 ...
- 什么是ISP,他的工作原理是怎样的?
ISP是Image Signal Processor的缩写,全称是影像处理器.在相机成像的整个环节中,它负责接收感光元件(Sensor)的原始信号数据,可以理解为整个相机拍照.录像的第一步处理流程,对 ...
- zoj 3882 Help Bob(zoj 2015年7月月赛)
Help Bob Time Limit: 2 Seconds Memory Limit: 65536 KB There is a game very popular in ZJU at pr ...
- Centos 通过yum的方式升级内核
在安装某些软件时,可能对我们的系统内核版本有要求. 比如在安装docker要满足一定的条件,对于centos系统,要求必须是64位,并且内核版本是3.10以上. 如果你的centos操作系统内核低于3 ...
- 底部菜单实现(Dialog方案)
项目中经常会要实现在屏幕底部弹出一个窗口,比如一个分享窗口: 下面详解实现步骤: 1.定义布局 <?xml version="1.0" encoding="utf- ...
- Solidworks如何为装配体绘制剖面视图
1 如图所示的工程图来自装配体 2 点击剖面视图,随后绘制一条线(我从正中劈开),弹出对话框,勾选自动打剖面线,确定 3 剖面视图绘制完毕 三个剖视图如下 关于半剖视图,可以这样做.先 ...
- vscode - emmet失效?
把emmet设置覆盖为用户.
- flask的分页功能
分页是个很通用的东西,在flask中,有一个macro的语法,类似于宏,我们可以将通用的东西通过macro写入单独的html文件以方便维护,减少代码量.下面是我的分页的macro文件render_pa ...
- Java-帮助文档的制作
Java-帮助文档的制作 1,public修饰的类才干够用bin/javadoc生成文档 2.java的说明书是通过文档的凝视来完毕的,所以在敲代码的时候.凝视是非常有必要的 使用文档凝视法,才干够生 ...
- JDBC技术总结(三)
1. 数据库连接池 JDBC部分的前两个总结主要总结了一下JDBC的基本操作,而且有个共同点,就是应用程序都是直接获取数据库连接的.这会有个弊端:用户每次请求都需要向数据库获得连接,而数据库创建连接通 ...