有向图找出所有从u到v的简单路径 以及 从u到v的长度为k的简单路径
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
const int maxn=205;
using namespace std;
class directGraph{
private:
int n,m;
bool vis[maxn];
vector<int> vec[maxn];
int dis[maxn][maxn];
public:
vector<vector<int> > allPath;
directGraph() {
memset(dis,0x3f,sizeof(dis));
printf("-------------构建有向图类-----------\n");
printf("请输入节点数:");
scanf("%d",&n);
for(int i=1;i<=n;i++) dis[i][i]=0;
printf("请输入边的数量:");
scanf("%d",&m);
printf("请输入 %d 条边的信息(u->v):\n",m);
for(int i=1,u,v;i<=m;i++) {
scanf("%d %d",&u,&v);
vec[u].push_back(v);
dis[u][v]=1;
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {
for(int k=1;k<=n;k++) {
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
}
void dfs(int u,int v,vector<int> path) {
if(dis[u][v]>n-1) {
return;
}
if(u==v) {
allPath.push_back(path);
return;
}
for(int i=0;i<vec[u].size();i++) {
if(!vis[vec[u][i]]) {
vis[vec[u][i]]=true;
path.push_back(vec[u][i]);
dfs(vec[u][i],v,path);
path.pop_back();
vis[vec[u][i]]=false;
}
}
}
void findAllSimplePath(int u,int v) {
allPath.clear();
memset(vis,false,sizeof(vis));
vector<int> path;
path.push_back(u);
vis[u]=true;
dfs(u,v,path);
int num=allPath.size();
if(num!=0) {
printf("从 %d 到 %d 的简单路径一共有 %d 条!\n",u,v,num);
for(int i=0;i<num;i++) {
printf("第 %d 条路径: ",i+1);
for(int j=0;j<allPath[i].size();j++) {
printf("%d",allPath[i][j]);
if(j==allPath[i].size()-1) printf("\n");
else printf(" -> ");
}
}
}else{
printf("没有从 %d 到 %d 的简单路径!\n",u,v);
}
}
void dfsk(int u,int v,int l,int k,vector<int> path) {
if(dis[u][v]>n-1) {
return;
}
if(u==v) {
if(l==k) allPath.push_back(path);
return;
}
if(l==k) return;
for(int i=0;i<vec[u].size();i++) {
if(!vis[vec[u][i]]) {
vis[vec[u][i]]=true;
path.push_back(vec[u][i]);
dfsk(vec[u][i],v,l+1,k,path);
path.pop_back();
vis[vec[u][i]]=false;
}
}
}
void findAllKPath(int u,int v,int k) {
allPath.clear();
memset(vis,false,sizeof(vis));
vector<int> path;
path.push_back(u);
vis[u]=true;
dfsk(u,v,0,k,path);
int num=allPath.size();
if(num!=0) {
printf("从 %d 到 %d 的长度为 %d 的简单路径一共有 %d 条!\n",u,v,k,num);
for(int i=0;i<num;i++) {
printf("第 %d 条路径: ",i+1);
for(int j=0;j<allPath[i].size();j++) {
printf("%d",allPath[i][j]);
if(j==allPath[i].size()-1) printf("\n");
else printf(" -> ");
}
}
}else{
printf("没有从 %d 到 %d 的长度为 %d 的简单路径!\n",u,v,k);
}
}
};
int main() {
directGraph g;
printf("----------------菜单如下所示---------------\n");
printf("0. 退出\n");
printf("1. 找从起点到重点的路径\n");
printf("2. 找从起点到终点的长度为k的简单路径\n");
printf("-------------------------------------------\n\n");
while(true) {
int opt;
printf("请输入操作:");
scanf("%d",&opt);
if(opt==0) break;
else if(opt==1) {
printf("请输入起点与终点编号:");
int u,v;
scanf("%d %d",&u,&v);
g.findAllSimplePath(u,v);
printf("\n");
}else if(opt==2) {
int u,v,k;
printf("请输入起点与终点编号:");
scanf("%d %d",&u,&v);
printf("请输入路径长度:");
scanf("%d",&k);
g.findAllKPath(u,v,k);
printf("\n");
}else{
printf("操作不合法!\n");
}
}
}