dfs求树的直径JAVA_week11求树的直径

week11:求树的直径;

随机选点,搜索到距离该点最远的一点,然后从该点出发获得最远点,两点间距即为直径;正常思路

然后看了眼大佬的代码。real服。空间换时间。

每当加入一条边:就当是两条边;

to数组存边号对应的终点,hd数组存起点对应的边号,nx数组存该起点对应的另一条边;

核心代码非常诡异:

int cl(int u,int p){

int a=0,b=0,t;

for(int i=hd[u];i;i=nx[i])//u的每一个方向

if(to[i]!=p)//如果没有走回起点

if((t=cl(to[i],u)+1)>b)//迭代取得u经过i边的最远。(即u为折点)

if((b=t)>a)

t=a,a=b,b=t;//之前t>b>a;现在a>b>t;

if((b+=a)>ans)ans=b;//该点一边最远a一边最远b;

return a;//经过u的最远;

}

这个代码倒是严格按提示来的,a保留了u开始最长,b保留了u开始次长;返回a+b;就是逻辑很难顺下来啊。

看了下poj1849的报告

1849的题是这样:n个点,n-1条有权边,从S点出发的两辆车 遍历完所有节点走过的路最短。

由题可知不成环。那么就只有两种情况:

1.起点在直径上,那么直接求树的直径就好

2.起点不在直径上:最长链只被遍历一遍,其余都是两遍

显然1是2的特殊情形。

用bfs吧 因为dfs经常用。

所以要S干嘛。。。觉得我随机找一点开始太浪费时间,从起点开始?

用数组模拟搞过了。

不过bfs的正规套路是queue啊。

步步为营 一视同仁 无解方止

queue q;

q.push(start);

Point next;

while(!q.empty())//队列不为空继续扩展

{

Point tmp=q.front();

q.pop();

for(int i = 0; i < 8; ++i)

{

next.row = tmp.row + directR[i];

next.col = tmp..col + directC[i];

if(inmap(next) && !visited[next.row][next.col])//inmap判断是否在地图内

{

next.moves = tmp.moves + 1;

if(next.row == end.row && next.col == end.col)//如果是终点

return next.moves;

q.push(next);//入列

visited[next.row][next.col] = true;//标志为走过

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值