状态压缩dp,经典MTSP问题,第一问比较容易求,先求出满足情况的状态放在了mov里面,然后模拟0-1背包的过程求出最少用多少judge。第二问就比较复杂了,第二问要求我们算出最短的时间,即最短总路程。这样的话就比较难求了。。。第二问看了一下网上大神的代码才懂的。。。汗。。。第二问,dt[i][j],表示当状态为i(注意:i & 1 == 1)时, 最后一个走过的节点是j时最短路径, best[i] 表示状态完成状态 i 需要的最短路径。然后具体实现还是看代码吧。。。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#define SL strlen
#define PB push_back
#define LL long long
#define INF 0X3f3f3f3f
#define CLR(a, b) memset(a, b, sizeof(a))
using namespace std;
const int N = 17;
struct Point
{
int x, y;
}p[N];
int dp[1 << N], c[N];
int dt[1 << N][N], best[1 << N];
int g[N][N];
vector<int> mov;
int n, m, i, j, k;
int len(Point a, Point b)
{
return ceil(sqrt((double)(a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)));
}
bool ok(int k)
{
int ret = 0; j = 0;
while(k)
{
if(k & 1)
{
ret += c[j];
}
k >>= 1;
j ++;
}
return ret <= m;
}
void input()
{
for(i = 0; i < n; i ++)
{
scanf("%d%d", &p[i].x, &p[i].y);
}
for(i = 0; i < n; i ++)
{
scanf("%d", &c[i]);
}
}
void work()
{
for(i = 0; i < n; i ++)
{
for(j = 0; j < n; j ++)
{
g[i][j] = len(p[i], p[j]);
}
}
mov.clear();
for(i = 1; i < (1 << n); i ++)
{
if(ok(i)) mov.PB(i);
}
}
bool solve()
{
CLR(dp, INF);
dp[0] = 0;
for(i = 0; i < mov.size(); i ++)
{
for(j = (1 << n) - 1; j >= 1; j --)
{
if((j & mov[i]) == mov[i])
{
dp[j] = min(dp[j], dp[j ^ mov[i]] + 1);
}
}
}
if(dp[(1 << n) - 1] == INF) { printf("-1 ");return 0; }
//else printf("%d ", dp[(1 << n) - 1]); return 1;
}
void TSP()
{
CLR(best, INF);
CLR(dt, INF);
dt[1][0] = 0;
for(i = 0; i < mov.size(); i ++)
{
for(j = 0; j < n; j ++)
{
if((1 << j) & mov[i])
{
best[mov[i]] = min(best[mov[i]], dt[mov[i]][j] + g[j][0]);
for(k = 0; k < n; k ++)
{
if(!((1 << k) & mov[i]))
{
dt[mov[i] | (1 << k)][k] = min(dt[mov[i] | (1 << k)][k], dt[mov[i]][j] + g[j][k]);
}
}
}
}
}
for(i = 1; i < (1 << n); i ++)
{
if(i & 1) for(j = i & (i - 1); j; j = i & (j - 1))
{
best[i] = min(best[i], best[j] + best[(i ^ j) | 1]);
}
}
printf("%d\n", best[(1 << n) - 1]);
}
int main()
{
//freopen("input.txt", "r", stdin);
while(scanf("%d%d", &n, &m) != EOF)
{
input();
work();
if(solve()) TSP();
else puts("-1");
}
}