Hamilton路径(DFS)

该题做法与分道扬镳(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
#include
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;
}

你可能感兴趣的:(题解,深搜广搜)