题意:
可多次拜访的类TSP问题。
思路:
状态转移方程:dp[s][v]=min(dp[s|{u}][u]+mp[u][v]) (u不属于s)
反思:
一个月没写代码,手都生疏了。五月份要加油!!!
代码:
#include <cstdio>
#include <vector>
#include <cmath>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = 20;
const int INF = 0x3f3f3f3f;
int n, m;
int graph[MAXN][MAXN];
int dp[(1 << MAXN) - 1][MAXN];
void init()
{
memset(graph, INF, sizeof(graph));
memset(dp, INF, sizeof(dp));
}
void floyd()
{
for(int i = 0; i < n; i++)
{
graph[i][i] = 0;
}
for(int k = 0; k < n; k++)
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]);
}
}
}
}
int solve()
{
floyd();
dp[(1 << n) - 1][0] = 0;
for(int k = (1 << n) - 2; k >= 0; k--)
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(!((k >> j) & 1))
dp[k][i] = min(dp[k][i], dp[k | (1 << j)][j] + graph[i][j]);
}
}
}
return dp[0][0];
}
int main()
{
int t; scanf("%d", &t);
while(t--)
{
init();
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
u--, v--;
graph[u][v] = min(graph[u][v], w);
graph[v][u] = min(graph[v][u], w);
}
printf("%d\n", solve());
}
}