##1.题目描述
给定一张包含N个点,N-1条边的无向连通图,节点从1到N编号,每条边长度为1。假设你从1号节点出发并打算遍历所有节点,那么路程至少是多少?
输入描述:
第一行输入一个整数N,1<=N<=10^5
接下来N-1行,每行包含两个数X,Y,表示X号节点到Y号节点之间有一条线,1<=X,Y<=N
输出描述:
输出总路径的最小值
样例输入:
4
1 2
1 3
3 4
样例输出:
4
##2.分析
以下述例子分析
1
/ | \
2 3 5
| \
4 6
\
7
可以看出,这个图,其实就是一颗普通树,那么1遍历的最短路径应该是:
1->2->1->3->4->3->1->5->6->7
其实,我们看出来,1节点到叶子节点有三条路径,分别是:
1->5->6->7 1->2 1->3->4
那么,我们队这三条路径长度从小到大排序,就是
1->2 1->3->4 1->5->6->7
那么我们更加每条路径长度推出节点1遍历路径的最小路程应该是:
2*(2-1)+2*(3-1)+(4-1)
所以,就是求根节点1到每条叶子节点的路径,从小到大排序,之后得到结果就很简单了。
##3.代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void findPath(vector<vector<int>>& lujin,int node,vector<int> &path)
{
auto iter = std::find(path.begin(),path.end(),node);
if(iter == path.end())
{
path.push_back(node);
for(int i=0;i<lujin[node].size();++i)
{
findPath(lujin,lujin[node][i],path);
}
}
}
void findPath(vector<vector<int>>& lujin,vector<vector<int>>& paths)
{
for(int i=0;i<lujin[0].size();++i)
{
vector<int> path;
path.push_back(0);
int node = lujin[0][i];
findPath(lujin,node,path);
paths.push_back(path);
}
}
int main()
{
int n;
cin>>n;
vector<vector<int>> lujin(n,vector<int>(0));
for(int i=0;i<n-1;++i)
{
int x,y;
cin>>x>>y;
lujin[x-1].push_back(y-1);
lujin[y-1].push_back(x-1);
}
//如果是样例输入,那么lujin的结果应该是:
//lujin[0]:1,2
//lujin[1]:0
//lujin[2]:0,3
//lujin[3]:2
vector<vector<int>> paths;
findPath(lujin,paths);
//paths的结果应该是:
//paths[0]:0,1
//paths[1]:0,2,3
vector<int> result;
for(int i=0;i<paths.size();++i)
{
result.push_back(paths[i].size());
}
std::sort(result.begin(),result.end());
//result结果是:2,3
int count=0;
for(auto iter=result.begin();iter!=result.end()-1;++iter)
{
count +=2*(*iter-1);
}
count +=*(result.end()-1)-1;
cout<<count<<endl;
return 0;
}