ACM入门之TSP问题

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM入门之TSP问题相关的知识,希望对你有一定的参考价值。




旅行商问题,即TSP问题是数学领域中著名问题之一。
假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。
路径的选择目标是要求得的路径路程为所有路径之中的最小值。

这是一个非常经典的问题,一般在ACM或者面试算法题中常见。
这里是用状压DP来解决该问题。

例题一:

这里的话是不用回来,且固定了起点终点。
f[i][j] 表示的是i状态下 终点是j的最小花费

#include<bits/stdc++.h>
using namespace std;
const int N=25;
int g[N][N],f[1<<21][25],n;
int main(void)

    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++) cin>>g[i][j];
    memset(f,0x3f,sizeof f);
    f[1][0]=0;
    for(int i=0;i<(1<<n);i++)
    
        for(int j=0;j<n;j++)
        
            if(i>>j&1)
            
                for(int k=0;k<n;k++)
                
                    int temp=i-(1<<j);
                    if(temp&1)
                    
                        f[i][j]=min(f[i][j],f[i-(1<<j)][k]+g[k][j]);
                    
                
            
        
    
    cout<<f[(1<<n)-1][n-1];
    return 0;

例题二:

先floyd(),之后就是经典模型了。这里没有确定起点和终点。

#include<bits/stdc++.h>
using namespace std;
const int N=210;
int g[N][N],f[1<<16][20],a[N];
int n,m,t;
int main(void)

	cin>>n>>m>>t;
	memset(f,0x3f,sizeof f);
	memset(g,0x3f,sizeof g);
	for(int i=1;i<=n;i++) g[i][i]=0;
	for(int i=0;i<t;i++) cin>>a[i];
	while(m--)
	
		int a,b,c; cin>>a>>b>>c;
		g[a][b]=g[b][a]=min(g[a][b],c);
	
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
	for(int i=0;i<t;i++) f[1<<i][i]=0;
	for(int i=0;i<(1<<t);i++)
	
		for(int j=0;j<t;j++)
		
			if(i>>j&1)
			
				for(int k=0;k<t;k++)
				
					if(i>>k&1)
					
						f[i][j]=min(f[i][j],f[i-(1<<j)][k]+g[a[k]][a[j]]);
					
				
			
		
	
	int ans=1e9;
	for(int i=0;i<t;i++) ans=min(ans,f[(1<<t)-1][i]);
	cout<<ans;
	return 0;

以上是关于ACM入门之TSP问题的主要内容,如果未能解决你的问题,请参考以下文章

TSP经典算例之遗传算法改进

TSP问题-可重复访问城市的解法

大学就是一段路程的终点

遗传算法求解TSP源码及解析

用遗传算法解决TSP问题

TSP基于matlab蜜蜂算法求解旅行商问题含matlab源码 1248期