该题做法与分道扬镳(DFS+剪枝+邻接表)是基本一样的。
题目:Hamilton路径
给出一个连通的有向图,求图中顶点1到顶点n的、经过其余顶点一次且仅一次的最短路径及其长度。
Input
单测试用例。
第一行是两个整数N,E,N表示顶点个数( 1 ≤ N ≤ 40 ),E表示弧的数量( N < E < 200 )。
接下来E行,每行是空格分隔的3个整数u, v, l,分别表示从顶点u发出一条长度为l的弧到顶点v。1 ≤ u, v, ≤ N 。 0 < l ≤ 100
注意:可能存在重边。
Output
每个测试用例输出:如果不存该路径,输出一行 “No solution”;
否则,输出两行:第1行,该最短路的长度;第2行,从顶点1到顶点n的最短路,顶点之间用一个空格分隔,要求按路径的顶点次序,前一个顶点必须有弧指向后一个顶点。
Sample Input
5 12
1 2 23
1 3 35
1 4 5
2 3 58
2 4 8
2 5 76
3 2 33
3 4 2
3 5 75
4 2 95
4 3 34
4 5 85
Sample Output
140
1 2 4 3 5
#include<iostream>
#include<vector>
const int inf=0x3f3f3f3f;
using namespace std;
struct node
{
int aim,len;
};
vector<node>a[45];
vector<int>q;
vector<int>ww;
int N,E,u,v,l,way;
bool book[45];
void dfs(int i,int road,int num)
{
if(road>way) //判断当前路径长度是否超过way来剪枝
return;
if(i==N&&num==N){
if(road<way)
way=road,ww.assign(q.begin(),q.end());///把整个vector数组q赋值给vector数组ww
return;
}
for(int j=0;j<a[i].size();j++){
if(!book[a[i][j].aim]){
book[a[i][j].aim]=1;
road+=a[i][j].len;
q.push_back(a[i][j].aim);
dfs(a[i][j].aim,road,num+1);
road-=a[i][j].len;
book[a[i][j].aim]=0;
q.pop_back();
}
}
return;
}
int main()
{
ios::sync_with_stdio(false);
struct node qq;
cin>>N>>E;
for(int i=1;i<=E;i++){
cin>>u>>v>>l;
qq.aim=v,qq.len=l,a[u].push_back(qq); ///建邻接表
}
way=inf;
book[1]=1;
q.push_back(1);
dfs(1,0,1);
if(way==inf){
cout<<"No solution"<<endl;
return 0;
}
cout<<way<<endl;
for(int i=0;i<ww.size();i++)
cout<<ww[i]<<' ';
cout<<endl;
return 0;
}