树的直径

来源:互联网 发布:电脑连接的常用端口 编辑:程序博客网 时间:2024/05/29 18:06

不带解释版模板O(n)常数较大, 但是可以知道树上每一点到直径端点的距离, 这个大多时候都很有用!

struct node{    int to,w,next;}e[maxn*2];ll dis1[maxn],dis2[maxn];int st,ed,max_len;void dd(int u,int fa,int len,int flag){    if(flag) dis1[u] = len;    if(!flag) dis2[u] = len;    if(len > max_len && flag) st = u, max_len = len;    for(int i=head[u]; ~i ; i = e[i].next){        int to = e[i].to;        if(to == fa) continue;        dd(to,u,len + e[i].w,flag);    }}    Fill(dis1,0); Fill(dis2,0);    max_len = -1;    dd(1,-1,0,1);    ed = st;    max_len = -1;    dd(st,-1,0,1);    swap(st,ed);    dd(ed,-1,0,0);

带解释版模板

//其余的不用关心.void dd(int u, int fa, ll len,int flag){ //flag不同代表不同的端点.}//dis1和dis2分别代表树的不同端点到树上每一个点的距离是多少.    Fill(dis1,0); Fill(dis2,0);    max_len = -1;    dd(1, -1, 0, 1);  //先随便找一个点进行搜索.    ed = st;            //搜到最远的那个点一定是树的直径的某一端.    max_len = -1;     dd(st, -1, 0, 1);  //在以这个点去搜索最远的那个点就是直径的另一个端点值.    swap(st, ed);    dd(ed, -1, 0, 0);   //把每一个端点对树上每一个点的距离都算了一遍.

附上一个单纯On求树的直径的, 只是单纯需要树的直径的, 有些题就是这样

int dfs(int u,int fa){    int fir=0,sec=0;    for(int i=0; i<g[u].size() ; i++){        int to = g[u][i];        if(fa == to ) continue;        int tmp = dfs(to,u);        if(tmp > fir) sec = fir,fir = tmp;        else if(tmp > sec) sec = tmp;    }    if( fir + sec > maxx) maxx = fir+sec;    return fir+1;}//实际上就是保存树上到的每一个点的最远距离和次远距离,然后不断更新答案即可.
原创粉丝点击