P8605 [蓝桥杯 2013 国 AC] 网络寻路
和简单寻找0-(n-1)的所有路径思路一致,细节处理有所不同。
1.本题为无向图 ,需要添加两条边
2.每一轮dfs如何确保不走回头路?1→2→3→1 是允许的。1→2→1→2 或者 1→2→3→2 都是非法的。只需判断下一个节点和父节点是否相同?
3.每一轮dfs结束,需要通过path.clear();
清空上一轮dfs遗留的元素。
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
//vector<vector<int>> result;
vector<int> path;
int ans=0;
void dfs(vector<vector<int>>& graph,int x,int fa)
{
//终止条件为找到一条节点数为4(长度为3)的路径
if(path.size()==4){
ans++;
//result.push_back(path);
return;
}
for(int i=0;i<graph[x].size();i++)
{
if(fa==graph[x][i])continue;//不走回头路,下一个节点和父节点相同时跳过
path.push_back(graph[x][i]);
dfs(graph,graph[x][i],x);
path.pop_back();//回溯
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,m;cin>>n>>m;
vector<vector<int>> graph(n);
//本题为无向图 ,添加两条边
for(int i=0;i<m;i++)
{
int u,v;cin>>u>>v;
graph[u-1].push_back(v-1);
graph[v-1].push_back(u-1);
}
for(int i=0;i<n;i++)
{
path.push_back(i);
dfs(graph,i,-1);
path.clear();//需要清空上一轮dfs遗留的元素
}
//输出所有合法路径
// for(int i=0;i<result.size();i++)
// {
// for(int j=0;j<result[i].size();j++)
// {
// if(j==result[i].size()-1)
// {
// cout << result[i][j];
// }else{
// cout << result[i][j] <<"->";
// }
// }
// cout <<endl;
// }
cout <<ans;
return 0;
}