修路

JD测试开发笔试题,修路。

题目提炼出来就是【找出两条路径的长度乘积最大,要保证这两条路径没有公共的点,如果找不到就输出0】,这是一道原题【Codeforces Beta Round #14 D - Two Paths】。

学习了很久终于明白了这道题怎么做的。

对于每条边,我们依次把这条边去掉的话,就可以把原图分割成了两棵树,然后就成了求这两棵树的最远两个节点的距离,然后把两棵树求出来的结果相乘,看能不能更新max_ans。

在求每棵树路径时,假如去掉的是[a,b]这条边,从a点走,他就不走b点,而是走除b点之外的另外的路,然后一直走到底,会得到一个值len1,然后a点走另一个方向(假如有路的话),走到底得到len2,找出最大的两条路,len1和len2。len1+len2就是a这边这棵树的最大的路径。然后再找出b那边的树的最大的路径长度。相乘。检查能否更新值。

然后接下来枚举下一条边。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 206;
vector<int> G[N];
int maxlen;
int res;
int dfs(int a, int b)
{
	int sum = 0;//两边的和,就是过a点的这条路的长度,这个函数就是为了找出最长的它
	int len1 = 0;//其中从a出发最长的一部分
	int len2 = 0;//从a出发的第2长的路径。len2+len1就是其中一条路径长
	for(int i = 0; i < G[a].size(); ++i)
	{
		if(G[a][i] != b)//线段【a,b】,从a开始寻找最长的路,由于[a,b]这条路断开,所以不走b点
		{
			sum = max( dfs(G[a][i], a) , sum);//下一个点继续走下去
			if(maxlen > len1)//更新最长的
			{
				len2 = len1;
				len1 = maxlen;
			}
			else if(maxlen > len2)//或者是更新第2长的
			{
				len2 = maxlen;
			}
		}
	}
	maxlen = len1 + 1;//更新边长,一条路走到底后,返回一步,长度加1。然后用它来判断是否需要更新当前最长的一部分路
	sum = max(sum, len1 + len2);
	return sum;
}

int main()
{
	int n;
	cin >> n;
	//把图构建好
	for(int i = 1; i < n; ++i)
	{
		int a, b;
		cin >> a >> b;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	//枚举每条边
	for(int i = 1; i <= n; ++i)
	{
		for(int j = 0; j < G[i].size(); ++j)
		{
			int l = dfs(i, G[i][j]);//从a点出发
			int r = dfs(G[i][j], i);//从b点出发
			res = max(res, l*r);
		}
	}
	cout << res << endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值