算法笔记--树的直径模板

思路:

利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点。

先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c之间的距离就是树的直径。

模板:

const int N=1e6+5;
int head[N];
int dis[N];
bool vis[N];
int cnt=0,b,mxn=0;
struct edge
{
    int to,w,next;
}edge[N];
void add_edge(int u,int v,int w)
{
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
void bfs(int s)
{
    queue<int>q;
    q.push(s);
    int now,nxt;
    mxn=0;
    b=s;
    mem(dis,0);
    mem(vis,false);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        for(int i=head[now];~i;i=edge[i].next)
        {
            if(!vis[edge[i].to])
            {
                q.push(edge[i].to);
                vis[edge[i].to]=true;
                dis[edge[i].to]=dis[now]+edge[i].w;
                if(dis[edge[i].to]>mxn)
                {
                    mxn=dis[edge[i].to];
                    b=edge[i].to;
                }
            }
        }
    }
}

poj 2631 Roads in the North

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int N=1e6+5;
int head[N];
int dis[N];
bool vis[N];
int cnt=0,b,mxn=0;
struct edge
{
    int to,w,next;
}edge[N];
void add_edge(int u,int v,int w)
{
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
void bfs(int s)
{
    queue<int>q;
    q.push(s);
    int now,nxt;
    mxn=0;
    b=s;
    mem(dis,0);
    mem(vis,false);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        for(int i=head[now];~i;i=edge[i].next)
        {
            if(!vis[edge[i].to])
            {
                q.push(edge[i].to);
                vis[edge[i].to]=true;
                dis[edge[i].to]=dis[now]+edge[i].w;
                if(dis[edge[i].to]>mxn)
                {
                    mxn=dis[edge[i].to];
                    b=edge[i].to;
                }
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int u,v,w;
    mem(head,-1);
    //freopen("in.txt","r",stdin);
    while(cin>>u>>v>>w)add_edge(u,v,w),add_edge(v,u,w);
    bfs(1);
    //cout<<b<<‘ ‘<<mxn<<endl;
    bfs(b);
    cout<<mxn<<endl;
    //fclose(stdin);
    return 0;
}

时间: 2024-10-10 11:27:12

算法笔记--树的直径模板的相关文章

拓扑排序,树的直径模板(CF14D 枚举删边)

HDU4607 树的直径 #include <stdio.h> #include <string.h> #include <iostream> #include <queue> #include <vector> using namespace std; #define N 100005 #define INF 1<<30 int n,dis[N],E; bool vis[N]; vector<int>G[N]; //注意

light oj 1094 Farthest Nodes in a Tree(树的直径模板)

1094 - Farthest Nodes in a Tree PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Given a tree (a connected graph with no cycles), you have to find the farthest nodes in the tree. The edges of the tree are weighted and undire

树的直径模板

1 struct stu 2 { 3 int from,to,val,next; 4 }st[M]; //定义结构体储存节点和节点间的距离以及下一个节点的位置 5 6 7 void init() 8 { 9 num=0; 10 memset(head,-1,sizeof(head)); 11 } //初始化函数 12 13 14 void add_edge(int u,int v,int w) 15 { 16 st[num].from=u; //储存节点u 17 st[num].to=v; //

&lt;学习笔记&gt; 树的直径 Bfs、Dfs

树的直径为树上最长的一条路径(不经过重复节点),也可以看做是树上最长路. 通常的求法: 1.两边Bfs或两边Dfs 2.树形dp(端点为根和仅经过根). emmm ..蒟蒻表示目前只会第一种QAQ. 从树中找出任意一点,求出与他距离最远的点s,再用同样的方法求出与s距离最远的点t,s-t即为树的直径. Bfs代码 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cma

算法笔记(树专题)

树专题 1.DFS模板 //伪代码 void DFS(一个结点){ 访问该结点; for(遍历该结点的相邻未访问过的结点){ 选此结点; DFS(这个邻接结点); 去掉刚刚选的结点; //****(勿忘) } } 2.BFS模板 //BFS使用队列 void BFS(int s){ queue<int> q; q.push(s); //起始点入队 while(!q.empty()){ 取出队首元素top; 访问队首元素top; 将队首元素出队; 将top的下一层结点中未曾入队的结点全部入队,并

POJ 1985--Cow Marathon【树的直径 &amp;&amp; 模板】

Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 4182   Accepted: 2116 Case Time Limit: 1000MS Description After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exercise, so he has com

[算法模版]树的重心和直径

[算法模版]树的重心和直径 树的重心 引自OI-WIKI 定义 以树的重心为根时,所有的子树(不算整个树自身)的大小都不超过整个树大小的一半. 找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心. 删去重心后,生成的多棵树尽可能平衡. 性质 树中所有点到某个点的距离和中,到重心的距离和是最小的:如果有两个重心,那么他们的距离和一样. 把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两个树的重心的路径上. 在一棵树上添加或删除一个叶子,那么它的重心最多只移动

【模板】tyvjP1520 树的直径 [2017年5月计划 清北学堂Day3]

P1520 树的直径 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 树的直径,即这棵树中距离最远的两个结点的距离.每两个相邻的结点的距离为1,即父亲结点与儿子结点或儿子结点与父子结点之间的距离为1.有趣的是,从树 的任意一个结点a出发,走到距离最远的结点b,再从结点b出发,能够走的最远距离,就是树的直径.树中相邻两个结点的距离为1.你的任务是:给定一棵树, 求这棵树中距离最远的两个结点的距离. 输入格式 输入共n行第一行是一个正整数n,表示这棵树的结点

算法笔记--lca倍增算法

算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; int anc[20][N]; int deep[N]; int h[N]; void dfs(int o,int u,int w) { if(u!=o)deep[u]=deep[o]+1,h[u]=h[o]+w; for(int j=0;j<g[u].size();j++) { if(g[u][j]!=o) { anc[0][g[u][j]]=u; for(int i=1;i<