hdu4284Travel 状态dp
2015-10-09 19:19
211 查看
//n个城市,m条路,过每条路需要花费钱 //在每个城市花费d[i]得到工作资格可以赚c[i]的钱 //现在手上有num钱,问能否从1点开始,在给定的h(h<=15)个城市找到 //工作在回到1点 //除了这h点的其他点不能工作,可以经过这h个点不工作 //可以先用一个floyd将任意两点的最短距离求出 //由于h很小,可以用状态压缩来做,1表示已经在这个城市工作过,0表示没有 //dp[i][j]表示状态为i,当前位置为j的最多的钱数 //然后用一个队列维护一下 #include<cstdio> #include<cstring> #include<queue> #include<iostream> using namespace std ; const int maxn = 110 ; const int inf = 0x3f3f3f3f ; int map[maxn][maxn] ; int n , m , num ; int p[maxn] , c[maxn] , d[maxn] ; int vis[1<<15][maxn] ; int dp[1<<15][15] ; 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() { //freopen("in.txt" , "r" , stdin) ; int t ; scanf("%d" , &t) ; while(t--) { scanf("%d%d%d" , &n , &m , &num) ; for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) map[i][j] = j == i ? 0 : inf ; for(int i = 1;i <= m;i++) { int u , v , w ; scanf("%d%d%d" , &u , &v , &w) ; if(map[u][v] > w) map[u][v] = map[v][u] = w ; } floyd() ; int h ; scanf("%d" , &h) ; for(int i = 0;i < h;i++) scanf("%d%d%d" , &p[i] , &c[i] , &d[i]) ; memset(dp , -1 , sizeof(dp)) ; queue<int>que ; memset(vis , 0 , sizeof(vis)) ; for(int i = 0;i < h;i++) if(num - map[1][p[i]] - d[i] > 0) { dp[1<<i][i] = num - map[1][p[i]] - d[i] + c[i] ; que.push(1<<i) ; que.push(i) ; vis[1<<i][i] = 1 ; } while(que.size()) { int s = que.front() ; que.pop() ; int pos = que.front();que.pop() ; vis[s][pos] = 0 ; for(int i = 0;i < h;i++) { if(((1<<i)&s) == 0 && dp[s][pos] - map[p[pos]][p[i]] - d[i] > 0) if(dp[s][pos] - map[p[pos]][p[i]] - d[i] + c[i] > dp[s^(1<<i)][i]) { dp[s^(1<<i)][i] = dp[s][pos] - map[p[pos]][p[i]] - d[i] + c[i] ; if(!vis[s^(1<<i)][i]) { que.push(s^(1<<i)) ; que.push(i) ; } } } } bool flag = false ; for(int i = 0;i < h;i++) if(dp[(1<<h)-1][i] - map[p[i]][1] > 0) { flag = true ; break ; } if(flag)puts("YES") ; else puts("NO") ; } return 0 ; }
相关文章推荐
- cocos2d 改掉游戏的图标和开始图片
- Fiddler
- HDU 1161 Eddy's mistakes(水~)
- Java中的CopyOnWrite容器
- python中的异常
- hadoop性能调优
- java打印日历
- 博弈论 + 按位异或
- HDU 5239 Doom [线段树]
- fianl
- [ACM] poj 3468 A Simple Problem with Integers(段树,为段更新,懒惰的标志)
- vmware 新机克隆
- 2015电赛点滴
- POJ 1753 Filp Game dfs
- [Leetcode]Peeking Iterator
- Linux网络编程socket错误分析
- 【work】输出所有能被3整除,且个位数为4或者百位数为4的四位数
- 科技英语写作
- 开通了CSDN博客,研究生阶段,只想每天记录点东西
- 查看memcached依赖的库