a.树的性质: .
- 树中所有节点都是连通的;
- 树上的任意连两点间只有一跳通路,即数中不能含有环;
- 性质1&2->含有n个节点的树有n-1条边;
- 树中任意节点的父节点只有一个,根节点除外;
- 性质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