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;
}