HDU 4284    Travel

有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1走完所有的他必须要去的城市,打完所有的工,并且成功回到起点1

由于H<=15,所以显然可以状压,预处理这些都必须去的城市之间的最短距离(可以floyd),然后状压DP[S][i]表示他到达了S这些城市后正处在第i个城市里(所以S & (1<<i) != 0)的剩余的最大的钱的数量,然后状态转移就好了

上面求最短路直接用的floyd不会错貌似是因为数据里没有Ci<Di的数据,因为如果存在这种情况的话,虽然不考虑点的花费最短路是可以到的但是实际确实到不了的,导致不能走完所有的H个城市:

1
3 3 5
1 2 1
2 3 1
1 3 10
3
1 8 5
2 2 10
3 20 5

比如这样的数据应该输出NO但答案是YES(被这种自己出的数据坑了好久啊有木有!!!)

 //#pragma comment(linker,"/STACK:102400000,102400000")
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 1e8
#define inf (-((LL)1<<40))
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
template<class T> T CMP_MIN(T a, T b) { return a < b; }
template<class T> T CMP_MAX(T a, T b) { return a > b; }
template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } //typedef __int64 LL;
//typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
//const LL MOD = 1000000007; int T, N, M, H, Money;
int dis[MAXN][MAXN], add[MAXN], cost[MAXN];
int citys[], dp[<<][]; void init()
{
int u, v, w, c, a;
mem0(add); mem0(cost);mem1(dp);
scanf("%d %d %d", &N, &M, &Money);
for(int i = ; i <= N ;i ++ )
{
dis[i][i] = ;
for(int j = ; j <= N ; j ++ )
if(i != j) dis[i][j] = INF;
}
for(int i = ; i < M; i ++ )
{
scanf("%d %d %d", &u, &v, &w);
dis[u][v] = dis[v][u] = MIN(dis[u][v], w);
}
scanf("%d", &H);
for(int i = ; i <= H; i ++ )
{
scanf("%d %d %d", &u, &a, &c);
citys[i] = u;
add[i] = a;
cost[i] = c;
}
} void floyd()
{
for(int k=;k<=N;k++)
for(int i=;i<=N;i++)
for(int j=;j<=N;j++)
{
dis[i][j] = MIN(dis[i][j], dis[i][k] + dis[k][j]);
}
} int main()
{
//FOPENIN("in.txt");
while(~scanf("%d", &T)) while(T--)
{
init();
floyd();
int ans = -INF; H += ;
citys[] = ; cost[] = add[] = ;
dp[][] = Money;
for(int now = ; now < (<<H); now ++ )
{
for(int u = ; u < H; u ++ ) if(dp[now][u] != -)
{
for(int v = ; v < H; v ++ ) if( (now & (<<v)) == )
{
int next = now | (<<v);
if(dp[now][u] >= dis[citys[u]][citys[v]] + cost[v] )
{
dp[next][v] = MAX(dp[now | (<<v)][v], dp[now][u] - dis[citys[u]][citys[v]] - cost[v] + add[v]);
}
if(next == (<<H) - )
{
ans = MAX(ans, dp[next][v]);
}
}
}
}
//printf("%d\n", ans);
printf("%s\n", ans >= ? "YES" : "NO");
}
return ;
}

最新文章

  1. 翻书插件:bookblock.js
  2. 基于2D-RNN的鲁棒行人跟踪
  3. c#控制打印机杂项
  4. $Ajax简单理解
  5. NSURLSession从网络上下载资源,此程序下载的是视频
  6. 【转】Unity3D研究院之通过C#使用Advanced CSharp Messenger(五十)
  7. 网页设计师必备的10个CSS技巧
  8. ConcurrentDictionary的ToDictionary
  9. [原]Android开发环境搭建
  10. 织梦DEDECMS {dede:field name=&#39;position&#39;/}标签增加其它属性的
  11. Scala是一门现代的多范式编程语言
  12. js或jquery实现图片轮播
  13. Linux一些命令
  14. 使用URL访问http服务器
  15. Monkey自动化脚本(一)
  16. ppt图片在word中不能正常显示,只显示为矩形框的解决方法
  17. 01 C语言程序设计--01 C语言基础--第1章 C语言概述&amp;第2章 GCC和GDB
  18. 使用Numpy将数据集中的data和target同时shuffle
  19. 试着理解cookie和session
  20. HDUOJ-----2066一个人的旅行

热门文章

  1. MVC+Ef项目(3) 抽象数据库访问层的统一入口;EF上下文线程内唯一
  2. 配置centos防火墙(iptables)开放80端口
  3. codevs 4919 线段树练习4
  4. PDO防注入原理分析以及使用PDO的注意事项 (转)
  5. js二级下拉被flash档住的解决办法
  6. equal 和 ==
  7. 使用C#代码审批/转签K2 Blackpearl流程
  8. Eclipse将android项目打包jar文件
  9. CMake实践(4)
  10. delphi 712 Word 2