HDU 5418 TSP(旅行商问题) 模板题

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5418

题目描述:

题目大意就是要你处理这样一个问题:从一个点出发,最后再回到原点,求所走的距离最少,并且要经过所有的城市.题目中给的数据范围很小:n<=16.所以我们可以想想状压DP
先用floyd预处理任意两个点之间的最短距离,为什么呢?因为在这道题中我们要用dp方程dp[s][i]
表示s表示已经经过的城市的集合,i表示现在正处在的城市。定义dp[s][i]为从i出发访问所有剩余的城市,再返回起点所需要的最短的路径。
然后我们就开始裸的状压啦
这篇博客讲得很好:https://blog.csdn.net/liujc_/article/details/48373141

程序代码:

#include
#include
#include
#include
#include
using namespace std;
int n,m,dis[20][20];
int t;
int dp[20][100000];
/*
s表示已经经过的城市的集合,v表示现在正处在的城市。
定义dp[s][v]为从v出发访问所有剩余的城市,再返回起点所需要的最短的路径。
mp[i][j] 表示 i 到 j 的最短路。 
*/
void floyd(){//球最短路
    for(register int k=0;kfor(register int i=0;ifor(register int j=0;jint main(){
    cin>>t;
    for(register int k=1;k<=t;++k){
        cin>>n>>m;
        memset(dis,0x3f,sizeof(dis));
        memset(dp,0x3f,sizeof(dp));
        for(register int i = 1;i<=m;i++) {
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c); a--;b--;
            dis[a][b]=min(dis[a][b],c);
            dis[b][a]=dis[a][b];
        }
        /*
        dp初始值为无穷大,一开始自己总是想不通为什么是(1<
        for(int i=0;i0;
        floyd();
        dp[0][(1<1]=0;
        for(register int s=(1<2;s>=0;--s) 
            for(register int i=0;ifor(register int j=0;jif(!(s>>j & 1)) {//如果当前城市j还没有经过,我们从i走向j
                        dp[i][s]=min(dp[i][s],dp[j][s|(1</*这个dp方程表示现在要从i走向j,而dp[j][s|(1<j这条边的权值
                        注意这里是从终点往起点推
                        */
                    }
        cout<0][0]<

你可能感兴趣的:(模板,状压)