据说是TSP经典问题。。。可以用状态压缩做。但是看到数据量,就厚着脸皮上搜索了。。。先floyd预处理每对点间的最小消费,然后只考虑要去的城市就可以了,这样的话城市数最多16个。。。当时就暴搜了。。。但是注意城市1如果也需要工作的话不一定是第一个工作的城市。。。
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #define INF 0X3f3f3f3f #define LL long long #define PB(a) push_back(a); #define CLR(a, b) memset(a, b, sizeof(a)) using namespace std; const int N = 222; const int H = 33; struct City { int num, c, d; }ct[H]; int g[N][N], m[H][H], h, n, mk; bool vis[H]; void floyd() { int i, j, k; for(k = 1; k <= n; k ++) { for(i = 1; i <= n; i ++) { for(j = 1; j <= n; j ++) { g[i][j] = min(g[i][j], g[i][k] + g[k][j]); } } } } bool dfs(int u, int my) { int i, j, f = 1; for(i = 0; i < h; i ++) if(!vis[i]) { f = 0; if(my - m[u][i] >= ct[i].d) { vis[i] = 1; if(dfs(i, my - m[u][i] - ct[i].d + ct[i].c)) return 1; vis[i] = 0; } } if(f && my < m[u][mk]) f = 0; return f; } int main() { int t, i, j, u, v, w, my, r; scanf("%d", &t); while(t --) { scanf("%d%d%d", &n, &r, &my); CLR(g, INF); for(i = 1; i <= n; i ++) { g[i][i] = 0; } for(i = 0; i < r; i ++) { scanf("%d%d%d", &u, &v, &w); g[u][v] = min(g[u][v], w); g[v][u] = g[u][v]; } scanf("%d", &h); mk = -1; for(i = 0; i < h; i ++) { scanf("%d%d%d", &ct[i].num, &ct[i].c, &ct[i].d); if(ct[i].num == 1) { mk = i; } } if(mk == -1) { mk = h; ct[h].num = 1; ct[h].c = 0; ct[h].d = 0; h ++; } floyd(); for(i = 0; i < h; i ++) { for(j = 0; j < h; j ++) { m[i][j] = g[ct[i].num][ct[j].num]; } } CLR(vis, 0); if(dfs(mk, my)) puts("YES"); else puts("NO"); } }