树的直径学习总结

来源:互联网 发布:saber软件芯片tl494 编辑:程序博客网 时间:2024/05/21 02:36

a.树的性质: .

  1. 树中所有节点都是连通的;
  2. 树上的任意连两点间只有一跳通路,即数中不能含有环;
  3. 性质1&2->含有n个节点的树有n-1条边;
  4. 树中任意节点的父节点只有一个,根节点除外;
  5. 性质4决定了一棵树只能含有一个根节点。
    注意:通过树的性质判断一个图是不是树。那就是判断图中所有节点是否连通(用并查集判断根节点是否唯一),图中是否含有环(判断边数是否为n-1)。一棵树的·根节点有且只有一个,但父节点可以有多个。

b.树的直径模板:
应用:查找树上到任意一点的最大距离
思想:从起点开始先找到一个与此点最远距离的点(用最短路径算法找最远路),记录此点,然后再以此点为起点找到离此点最远的点,一共用了两次最短路


struct Edge{    int from;    int to;     int val;    int next;}edge[MAXN];void init()//初始化函数{    memset(head,-1,sizeof(head)); edgenum=0;}void addedge(int u,int v,int w)/加边{    Edge E={u,v,w,head[u]};//用这种方式初始化结构体中变量顺序不能颠倒      edge[edgenum]=E;   //错误现象:死机状态     head[u]=edgenum++;//edgenum为总变数的2倍(无向图)注意数组大小}void bfs(int s)//s为开始节点 {    memset(dis,0,sizeof(dis));  memset(vis,false,sizeof(vis));    queue<int> que;  que.push(s); dis[s]=0; vis[s]=true; ans=0;    while(!que.empty())     {        int now=que.front(); que.pop();        for(int i=head[now];~i;i=edge[i].next)        {              int go=edge[i].to;              if(!vis[go])              {                  if(dis[go]<dis[now]+edge[i].val)  dis[go]=dis[now]+edge[i].val;//                if(ans<dis[go])//                {//                     ans=dis[go];//                     Tnode=go;//                  }                    vis[go]=true;                    que.push(go);              }         }     }    for(int i=1;i<=n;++i)//跑的和在里面差不多 两种用法具体判断     {        if(ans<dis[i])        {            ans=dis[i];//ans的更新不能少             Tnode=i;        }    }}

详细推导:http://www.cnblogs.com/wuyiqi/archive/2012/04/08/2437424.html

0 0
原创粉丝点击