[状压dp]经典TSP

时间:2023-03-08 22:22:34

0出发 每个顶点经过一次 回到0 最小花费.

O($n^2 \times 2^n$)

记忆化搜索:

 //  s: 已经访问过的节点状态  v: 出发位置
int dfs(int s, int v)
{
if(dp[s][v]>=)
return dp[s][v];
if(s==(<<n)- && v==) // 所有都走过 并 回到0
return dp[s][v]=;
int ans=INF;
for(int u=;u<n;u++)
if(!(s>>(u &))) // u没走过 则走到u
ans=min(ans, dfs(s | (<<u), u)+mp[v][u]);
return dp[s][v]=ans;
}
int main()
{
memset(dp, -, sizeof(dp));
printf("%d\n", dfs(, ));
return ;
}

直接dp:

         memset(dp, , sizeof(dp));
dp[(<<n)-][]=;
for(int s=(<<n)-;s>=;s--)
for(int v=;v<n;v++)
for(int u=;u<n;u++)
if(!(s>> u & ))
dp[s][v]=min(dp[s][v], dp[s | <<u][u]+mp[v][u]);
printf("%d", dp[][]);