HDU 4571 - Travel in time(Floyd+dijkstra+dp)
来源:互联网 发布:winscp linux版 编辑:程序博客网 时间:2024/05/22 13:16
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=4571
题意:
N个点M条边时限T,起点S终点E。
每个点都有其参观获得值以及花费,经过是可以选择参观或者是不参观,且下一个参观的地点价值比上一个要大。
M条无向边,每条边都有时间花费。
求出在时限内从起点到终点的所得最大值。
思路:
一次floyd,求出各点中间的最短路,为的是重新建有向图,因为参观地点的顺序是有要求的,符合要求的两个点连边。
须建源点和汇点,以解决参观或不参观的问题。
dp【i】【j】表示到i个点时间花费为j是的最大价值。在dijkstra中跑。
比赛时的想法是dp【i】【0/1】表示在i点取或者不取,但是状态太多,改了很久超时和爆内存。。。
AC.
#include <iostream>#include <cstdio>#include <vector>#include <cstring>#include <queue>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 150;int N, M, T, S, E;int cost[maxn], valu[maxn];int dist[maxn][maxn];struct edge { int to, c; edge(int tt, int cc) { to = tt; c = cc; }};vector<edge> g[maxn];void init(){ memset(dist, 0x3f, sizeof(dist)); for(int i = 0; i <= N; ++i) { dist[i][i] = 0; }}void floyd(){ for(int k = 0; k < N; ++k) { for(int i = 0; i < N; ++i){ for(int j = 0; j < N; ++j) { dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]); } } }}typedef pair<int, int> pir;int dp[maxn][maxn*3];void dij(){ priority_queue<pir, vector<pir>, greater<pir> > que; memset(dp, 0, sizeof(dp)); que.push(pir(0, N)); dp[N][0] = 0; while(!que.empty()) { pir p = que.top(); que.pop(); int v = p.second, cv = p.first; for(int i = 0; i < g[v].size(); ++i) { edge e = g[v][i]; int cnt = cv + e.c + cost[e.to]; if(cnt <= T && dp[e.to][cnt] < dp[v][cv] + valu[e.to]) { dp[e.to][cnt] = dp[v][cv] + valu[e.to]; que.push(pir(cnt, e.to)); } } } int ans = 0; for(int i = 0; i <= T; ++i) { ans = max(ans, dp[N+1][i]); } printf("%d\n", ans);}void build(){ for(int i = 0; i <= N+1; ++i) { g[i].clear(); } for(int i = 0; i < N; ++i) { for(int j = 0; j < N; ++j) { if(dist[i][j] != INF) { if(valu[i] < valu[j]) g[i].push_back(edge(j, dist[i][j])); //else g[j].push_back(edge(i, dist[i][j])); } } } for(int i = 0; i < N; ++i) { if(i == S) { g[N].push_back(edge(S, 0)); } else { g[N].push_back(edge(i, dist[S][i])); } if(i == E) { g[E].push_back(edge(N+1, 0)); } else { g[i].push_back(edge(N+1, dist[i][E])); } }}int main(){ //freopen("in", "r", stdin); int Cas; scanf("%d", &Cas); for(int cas = 1; cas <= Cas; ++cas) { scanf("%d %d %d %d %d", &N, &M, &T, &S, &E); for(int i = 0; i < N; ++i) { scanf("%d", &cost[i]); } for(int i = 0; i < N; ++i) { scanf("%d", &valu[i]); } init(); for(int i = 0; i < M; ++i) { int u, v, c; scanf("%d%d%d", &u, &v, &c); dist[u][v] = min(dist[u][v], c); dist[v][u] = min(dist[v][u], c); } printf("Case #%d:\n", cas); floyd(); build(); dij(); } return 0;}
0 0
- HDU 4571 - Travel in time(Floyd+dijkstra+dp)
- hdu 4571 Travel in time(floyd+dp)
- HDU-4571 Travel in time (Floyd&&(DFS||DP))
- Hdu 4571 Travel in time(dp)
- hdu 4571 Travel in time (Floyd+记忆化搜索)
- hdu 4571 Travel in time(SPFA+DP)
- HDU 4571——Travel in time(dp)
- 2013 长沙邀请赛 HDU 4571 Travel in time(dp)
- floyd+动态规划 hdu-4571-Travel in time
- hdu 4571 Travel in time(Floyd+记忆化)
- hdu 4571 Travel in time (floyd+分组背包)
- HDU 4571 Travel in time (SPFA 或 dp)
- hdu 4571 Travel in time 最短路+dp
- hdu 4571 Travel in time
- hdu 4571 Travel in time
- HDU -4571--Travel in Time
- hdu 4571 Travel in time
- hdu 4571 Travel in time
- 黑马程序员——c语言基础:运算符和分支结构的一些注意点和练习
- #if #ifdef #if defined 区别
- MFC多线程及实例
- APM for .NET评测系列:OneAPM vs SCOM
- 数据结构及概念分析总结
- HDU 4571 - Travel in time(Floyd+dijkstra+dp)
- Android圆角Button和点击效果的结合
- JAVA 内存管理总结
- 简析Hadoop的三种运行模式
- 反弹stage shellcode到meterpreter
- java内存空间详解
- minicom
- 动态规划----最长公共子序列
- ubuntu php版本更新