原题链接:[蓝桥杯][历届试题]网络寻路
分析题目要求:
-
首相明确有两种目的地,一种是回到原点,一种是到达一个没有到过的地方;
-
路径中经过的点不能够有重复的点;
-
根据题目给出的数据可以发现,1-2-3-4 和 4-3-2-1是两条不同的路径。
解体思路:
1.使用vis[]数组记录经过的点;
2.使用DFS寻找可能的路径,因为路径的长度是4,那么当寻找路径上的前3个点的时候,如果可以从前一个点走到当前的点,并且当前的点没有走过,那么将当前的点设置为路径当中的点。
3.寻找路径第四个点的时候,有两种可能的情况,一种是可以到达的第四个点是之前没有走过的点,方案数量加一,另外一的情况是可以到达的第四个点是第一个点(走回到了起点),方案数量加一。
注意事项:
1.使用vector创建一个邻接表,如果使用邻接矩阵,容易时间超限。
参考程序1:
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
int M,N,u,v,ans;
const int maxn=10010;
vector<int>G[maxn];
bool used[maxn];
//u表示上一个顶点,dep表示当前寻找第dep+1个结点,s表示起点;
void DFS(int u,int dep,int s){
if(dep==3){
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(!used[v] || v==s) ans++;
}
return ;
}
else{
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(!used[v]){
used[v]=true;
DFS(v,dep+1,s);
used[v]=false;
}
}
}
return ;
}
int main(void){
cin>>N>>M;
for(int i=1;i<=M;i++){
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
memset(used,0,sizeof(used));
for(int i=1;i<=N;i++){
used[i]=true;
DFS(i,1,i);
used[i]=false;
}
cout<<ans;
return 0;
}
参考程序2:只是我很久之前写的,代码风格不是很好
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#define maxn 100100
using namespace std;
int n,m,vis[maxn/10],ans;
typedef struct Road{
int start,end;
}Road;
vector<int> box[maxn/10];
void dfs(int f,int pre,int cur)
{
if(cur<=2)
{
for(int i=0;i<box[pre].size();i++)
{
int next=box[pre][i];
if(!vis[next])
{
vis[next]=1;
dfs(f,next,cur+1);
vis[next]=0;
}
}
}
if(cur==3)
{
for(int i=0;i<box[pre].size();i++)
{
int next=box[pre][i];
if(!vis[next]) ans++;
if(next==f) ans++;
}
}
}
int main(void)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int start,end;
scanf("%d%d",&start,&end);
box[start].push_back(end);
box[end].push_back(start);
}
for(int i=1;i<=n;i++)
{
vis[i]=1;
dfs(i,i,1);
vis[i]=0;
}
printf("%d",ans);
return 0;
}
网友评论