http://acm.hdu.edu.cn/showproblem.php?pid=4284
题意:n个城市,m条边,以及初始的钱数;下面m行给出每条边的u、v以及花费;然后是h个城市,每行给出城市编号、能赚的钱、买证的钱;PP要去这h个城市打工并且返回1城市(起点是1),要在该城市打工就得先买证,问PP能否成功;
DFS+Floyd
#include<stdio.h> #include<string.h> #define inf 1e9 const int maxn = 110; int map[maxn][maxn]; bool vis[maxn]; int n, m, init, h; bool flag; struct node { int id, c, d; }nod[maxn]; void Init() { flag = false; memset(vis, false, sizeof vis); for(int i = 1;i<=n;i++) { for(int j = 1;j<=n;j++) { if(i == j) map[i][j] = 0; else map[i][j] = inf; } } } void dfs(int u, int num) { if(num == h) { if(init - map[u][1] >= 0) { flag = true; return; } } if(flag) return; for(int i = 1;i<=h;i++) { int v = nod[i].id; if(map[u][v] != inf && (init-map[u][v])>=nod[i].d && !vis[v]) { vis[v] = true; init += (nod[i].c - nod[i].d - map[u][v]); dfs(v, num+1); vis[v] = false; init -= (nod[i].c - nod[i].d - map[u][v]); } } } void Floyd() { for(int k = 1;k<=n;k++) { for(int i = 1;i<=n;i++) { for(int j = 1;j<=n;j++) { if(map[i][j] > map[i][k]+map[k][j]) map[i][j] = map[i][k]+map[k][j]; } } } } int main() { int cas; scanf("%d", &cas); while(cas--) { scanf("%d%d%d", &n, &m, &init); Init(); while(m--) { int u, v, w; scanf("%d%d%d", &u, &v, &w); if(u == v) continue; if(map[u][v] > w) map[u][v] = map[v][u] = w; } Floyd(); scanf("%d", &h); for(int i = 1;i<=h;i++) scanf("%d%d%d", &nod[i].id, &nod[i].c, &nod[i].d); dfs(1, 0); if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }
状压DP
#include<stdio.h> #include<string.h> #include<algorithm> #define inf 1e9 using namespace std; const int maxn = 110; int dp[1<<16][20]; int n, m, h, money; int map[maxn][maxn]; struct Node { int id, ci, di; }node[20]; void init() { memset(dp, -1, sizeof dp); for(int i = 1;i<=n;i++) { for(int j = 1;j<=n;j++) { if(i == j) map[i][j] = 0; else map[i][j] = inf; } } } void Floyd() { for(int k = 1;k<=n;k++) { for(int i = 1;i<=n;i++) { for(int j = 1;j<=n;j++) map[i][j] = min(map[i][j], map[i][k]+map[k][j]); } } } int main() { int cas; scanf("%d", &cas); while(cas--) { scanf("%d%d%d", &n, &m, &money); init(); while(m--) { int u, v, w; scanf("%d%d%d", &u, &v, &w); if(map[u][v] > w) map[u][v] = map[v][u] = w; } Floyd(); scanf("%d", &h); for(int i = 0;i<h;i++) { scanf("%d%d%d", &node[i].id, &node[i].ci, &node[i].di); int v = node[i].id; int val = money - map[1][v] - node[i].di; if(val >= 0) dp[1<<i][i] = val + node[i].ci; } int st = 1<<h; for(int i = 1;i<st;i++) { for(int j = 0;j<h;j++) { if(dp[i][j] == -1) continue; for(int k = 0;k<h;k++) { if(i & (1<<k)) continue; int val = dp[i][j] - map[node[j].id][node[k].id] - node[k].di; if(val >= 0) dp[i|(1<<k)][k] = max(dp[i|(1<<k)][k], val+node[k].ci); } } } int ans = -1; for(int i = 0;i<h;i++) { ans = max(ans, dp[st-1][i] - map[node[i].id][1]); } if(ans != -1) printf("YES\n"); else printf("NO\n"); } return 0; }