打印u、v之间的所有简单路径(邻接表实现)
或许可以直接叫“打印u、v之间的所有路径”。
这个算法用处很多,可以用来找满足条件的最优路径。为了效率的考虑,用了邻接表实现。
#include <bits/stdc++.h>
#define N 1005
using namespace std;
int used[N]; //标记该节点是否已被使用
int path[N],d;
vector<int> g[N]; //邻接表
void FindPaths(vector<int> g[],int u,int v,int path[],int d); //局部变量传参版
void FP(vector<int> g[],int u,int v); //全局变量版,其实两个版本算法几乎一模一样
int main() {
int n,m,a,b,u,v;
//int d=0,path[N];
cin>>n>>m; //分别输入顶点和边的个数
for (int i=0;i<m;i++) {
cin>>a>>b; //输入边节点
g[a].push_back(b);
g[b].push_back(a);
}
cin>>u>>v; //输入待查询节点,查询从u到v的所有简单路径
//FindPaths(g,u,v,path,d);
FP(g,u,v); //全局变量版
return 0;
}
void FindPaths(vector<int> g[],int u,int v,int path[],int d) { //局部变量传参版
path[d++]=u; //当前节点在路径中的序号
used[u]=1; //标记当前节点已被使用
if (u==v) //如果遍历到了目标节点,就打印路径
for (int i=0;i<d;i++)
printf("%d%c",path[i],i==d-1?'\n':' ');
for (int i=0;i<(int)g[u].size();i++) //否则,就遍历u的所有邻点,继续调用此函数
if (!used[g[u][i]])
FindPaths(g,g[u][i],v,path,d);
used[u]=0; //回溯,需要重新把u节点改为从未使用
}
void FP(vector<int> g[],int u,int v) {
path[d++]=u;
used[u]=1;
if (u==v)
for (int i=0;i<d;i++)
printf("%d%c",path[i],i==d-1?'\n':' ');
for (int i=0;i<(int)g[u].size();i++)
if (!used[g[u][i]])
FindPaths(g,g[u][i],v,path,d);
used[u]=0;
d--; //回溯,由于d不再是参数,递归时该子函数执行完毕,返回母函数所以需要重新-1
}