奇怪的Andy,奇怪的旅行(无向图——邻接链表)
Posted 我永远信仰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了奇怪的Andy,奇怪的旅行(无向图——邻接链表)相关的知识,希望对你有一定的参考价值。
题目:
在地球上有一个奇怪的国家,这个国家有 n 个城市,但却只有 n−1 条道路,但是每个城市之间都可以互相到达。
某天 Andy 来到了这个国家,但是他以前没有出去旅游,真是个奇怪的人呢。他来到了这个国家进行一次旅行,想花尽量少的钱走过更多的城市,
他不想走回头路,因为这样会多花钱,真是个抠门的人呢。已知的是 Andy 可以任意选一个城市作为他旅行的起点。现在他找到你,他想知道他最多能走过多少个城市。
【输入格式】
第一行一个整数 n 表示这个国家的城市数量。
接下来 n−1行,每一行有两个整数 (u,v) 表示u,v之间有一条边。
tips: 1<=n<=100000
【输出格式】
输出一个数字,表示 Andy最多能走过多少个城市
【样例输入】
3
1 2
1 3
【样例输出】
3
tips: Andy可以按照城市2 −> 城市1 −> 城市3的路线进行旅行。
分析:
题意意思是,给n个点,共有n-1条边,且保证每个城市都能相互抵达
====>
推出结论,该城市构成的图无环形成(画一画就知道了),所以不需要考虑环的问题。因为可以相互抵达,所以这是一个无向图。
题目需要我们求图的最长的路径
1.解题思路
2.如何实现思路
3.介绍方法中使用的数据结构
4.源代码
下面以该例子讲解题解
1.无向图求最大路径解法(有向图中无效)
第一步:
任意
选取一个结点start
,然后从该节点出发,求能达到的最大路径–>进行一次深度搜索,得到距离最远的城市end
(可能有多个,但题目不要求输入所有答案,所以只记录一个即可,结果都是一样的);第二步:注意:这一步需要从
end
结点出发,重复第一步。比如:
选取了结点
1
,从1
出发,那么能达到的最远的结点是4
,经过的城市一共是3个.然后从
4
出发,能到达的最远节点是2
,经过的城市一共是4个.答案是4。
不证明了,百度一下,或者画两个其他例子的图自己试试说服自己。
2.如何实现思路
听说大家树学得很棒。可以将这个无环图看成树。在我们选取一个节点的时候,将这个结点当成一个根节点,与它相邻的结点当成孩子结点。那么问题转换成了求树的深度。
以结点1
为根节点的树
以结点4
为根节点的树
3.介绍方法中使用的数据结构、
对于每一个节点而言,它的孩子结点数量都是不一样的,比如上图中有1,也有2.
这里使用
vector
来对每一个结点,存储他的孩子节点。节省内存空间
vector
:C++ 的一个STL容器
- 类似于数组,可以直接使用下标访问。
- 动态的增加和删除,长度也会变化
//定义一个能存储int类型的动态数组,初始容量为n,但不会固定,默认值为0
vector<int> v(n);
int a[n]; //固定n长度
int len=v.size(); //求长度,len=n
v[0]=22; //将22赋值给v下标为0 此时v=22,n-1个0 len=n
v.push_back(33); //将33插入到v的队尾 此时v=22,n-1个0,33 len=n +1
v.pop_back(); //删除最后一个,此时v=22,n-1个0 len=n
更具体 百度
4.源码
#include <iostream>
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<map>
#include<math.h>
using namespace std;
/**
*
**/
int maxNum=0; //最多能走过城市的数量
int start=1; //起点
void dfs(vector<vector<int> > graph,int num,int depth,int flag[]);
int main()
int n;
scanf("%d",&n);
vector<vector<int> > graph(n+1);//存各个点
int flag[n+1]=0;//用来标记该点是否遍历过
int a,b;
//建立与该点相连的城市
for(int i=0;i<n-1;i++)
scanf("%d %d",&a,&b);
graph[a].push_back(b);//插入
graph[b].push_back(a);//插入
/**
*输出每个点与哪一个点相连
*/
for(int i=1;i<=n;i++)
vector<int> v=graph[i];
int len =v.size();
printf("与城市 %d 相邻的城市有: ",i);
for(int j=0;j<len;j++)
printf(" %d",v[j]);
printf("\\n");
//任意选一个点,这里默认设置选城市1,进行dfs,得到以该点为起点的的最大路径
dfs(graph,start,0,flag);//参数 2:城市起点 3:去过的城市数量总和
printf("起点为:%d\\n",start);
//重置一下第一次的记录
maxNum=0;
memset(flag, 0, sizeof(flag));//数组清0
//以该点位起点,再进行一次dfs.得到答案。
dfs(graph,start,0,flag);
printf("终点为:%d\\n",start);
printf("Andy最多能走过 %d 个城市\\n",maxNum);
system("pause");
return 0;
void dfs(vector<vector<int> > graph,int num,int depth,int flag[])
if(depth>=maxNum)
start=num;
if(flag[num]==1)//已经遍历,跳过
return;
depth++;
maxNum=max(depth,maxNum);
vector<int> v=graph[num];
int len =v.size();
flag[num]=1;
for(int j=0;j<len;j++)
if(flag[v[j]]!=1) //遍历过的,跳过
dfs(graph,v[j],depth,flag);
以上是关于奇怪的Andy,奇怪的旅行(无向图——邻接链表)的主要内容,如果未能解决你的问题,请参考以下文章