有向图找出所有从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" ) ;
}
}
}