输入:
门的数量
接下来N行,第i行描述编号为i(1~N)的门背后能通向的门:K D[1] D[2] ... D[K]
输出:
距离入口最远的门的编号
分析:
因为门的数量N<10的五次方,所以如果使用数组一定会出现段错误
因为求最远路径问题,想到深度优先搜索,所以使用邻接矩阵?邻接表?存储,用邻接矩阵的深度优先遍历算法?但是怎么求长度呢
还是使用Dijkstra算法这个算最短路径的算法改编为最长路径?but这个算法到现在也没记住
还有一个问题,入口是什么,难道要使用floyd算法吗,but同样的,没记住这个算法
思考结果:
问题解决应该分为两步:
1.寻找入口
2.寻找最远的那扇门,即最长路径
那么,如何寻找入口?题目说“007发现不存在两条路通向同一扇门”并且"题目保证这样的结果是唯一的",所以,入口有且只有一个,并且没有道路可以通向这个入口,即只能进,不能出
另一个问题,如何寻找最长路径呢?直观感觉并且思考会的知识之后,应该使用递归算法、
最后,使用什么存储通向的数据呢?使用c++的vector容器吧,不会出现段错误,(说到这里,似乎应该整理一下vector优势的知识点啦)c++知识点整理:vector的优势_HBUcs2020的博客-CSDN博客
问题分析完成,下面是代码:
应该注意
1.dfs中的迭代器为door1的
#include<iostream>
using namespace std;
#include<vector>
#include<cstring>
constexpr int MAXSIZE=100001;
vector<int> v[MAXSIZE];
int deep=0; //最大深度
int door; //最远门
void DFS(int door1,int deep1)
{
//printf("门为%d 深度为%d\n",door,deep);
if(deep1>deep)
{
deep=deep1;
door=door1;
}
for(vector<int>::iterator it=v[door1].begin();it!=v[door1].end();it++)
DFS(*it,deep1+1);
}
int main()
{
bool vis[MAXSIZE]; //是否有通向该门的道路
memset(vis,false,sizeof(vis));
int N;
cin>>N;
for(int i=1;i<=N;i++)
{
int k;
cin>>k;
while(k--)
{
int n;
cin>>n;
vis[n]=true;
v[i].push_back(n);
}
}
//入口
int i;
for(i=1;i<=N;i++)
{
if(!vis[i])
break;
}
//cout<<"最远的门"<<endl;
door=i; //入口
DFS(i,1);
cout<<door<<endl;
return 0;
}
好像还有使用bfs广度优先遍历和使用队列来解决的
代码如下,有时间再来看
1.使用队列
注意for(auto i:v[t])的使用,
好像这个思路有些许的熟悉,最后队列的使用方法类似简单计算器。
#include <bits/stdc++.h> using namespace std; #define N 100005 vector<int> v[N]; bool visit[N]={false}; int main() { int n,k,t; cin>>n; for(int i=1; i<=n; i++){ cin>>k; while(k--){ cin>>t; visit[t]=true; v[i].push_back(t); } } int start,res=1; for(start=1; start<=n; start++) if(!visit[start]) break; queue<int> q; q.push(start); while(!q.empty()){ t=q.front(); for(auto i:v[t]) q.push(i); q.pop(); if(q.size()==1) res=q.front(); } cout<<res; }
2.广度优先搜索
好像跟上面的队列是同一种方法
还没有看
#include<bits/stdc++.h> #define Maxsize 100001 using namespace std; int n; vector<int>v[Maxsize];///记录表格 bool vis[Maxsize];///记录是否路径通向当前点 int tt;///记录最远的那扇门 ///广度优先遍历 void BFS(int t){ queue<int>q; q.push(t); while(!q.empty()){ tt=q.front(); q.pop(); for(vector<int>::iterator it=v[tt].begin();it!=v[tt].end();it++) q.push(*it); } } int main(){ memset(vis,false,sizeof(vis)); cin>>n; for(int i=1;i<=n;i++){ int m; cin>>m; while(m--){ int d; cin>>d; vis[d]=true;///证明点门i能通向门d v[i].push_back(d); } } ///寻找入口 int i; for(i=1;i<=n;i++){ if(!vis[i]) break; } ///广度优先遍历最后一个结点 BFS(i); cout<<tt; return 0; }