BZOJ 1003 物流运输【最短路】【动态规划】
2016-01-10 15:15
393 查看
这道题数据太小啦!先枚举i,j表示从第i天到第j天不更改航线的费用。
然后直接跑最短路算法(我用的是Q版男朋友算法)
动归方程显然是f[i] = min(f[i], f[j] + cost[j+1][i] + k)
(PS:这道题一开始看成了某航线是否被ban...大家要注意啊!还有n和m的问题,各种别扭...)
代码(Submit Time
2016-01-10 15:48:24):
然后直接跑最短路算法(我用的是Q版男朋友算法)
动归方程显然是f[i] = min(f[i], f[j] + cost[j+1][i] + k)
(PS:这道题一开始看成了某航线是否被ban...大家要注意啊!还有n和m的问题,各种别扭...)
代码(Submit Time
2016-01-10 15:48:24):
#include <cstdio> #include <deque> using namespace std; const int maxd = 105; const int maxn = 25; const int INF = 1000000007; int d, n, k, m, q; int cost[maxd][maxd]; int f[maxd]; bool ban[maxn * maxn][maxd]; bool ava[maxd]; int min(int a, int b) { return a < b ? a : b; } int getint() { int r = 0, k = 1; char c; for (c = getchar(); c < '0' || c > '9'; c = getchar() ) if (c == '-') k = -1; for (; '0' <= c && c <= '9'; c = getchar() ) r = r * 10 - '0' + c; return r * k; } struct edge_type { int v, next, w; } edge[maxn * maxn]; int cnte = 0, h[maxn]; void ins(int u, int v, int w) { edge[++cnte].v = v; edge[cnte].w = w; edge[cnte].next = h[u]; h[u] = cnte; } deque<int> Q; int dis[maxn]; bool inque[maxn]; void SPFA() { Q.push_back(1); dis[1] = 0; inque[1] = true; for (int i = 2; i <= n; ++i) dis[i] = INF; int now; while (!Q.empty()) { now = Q.front(); Q.pop_front(); inque[now] = false; for (int i = h[now]; i; i = edge[i].next) { int v = edge[i].v; if (!ava[v]) continue; if (dis[v] > dis[now] + edge[i].w) { dis[v] = dis[now] + edge[i].w; if (!inque[v]) { Q.push_back(v); inque[v] = true; } } } } } int main() { d = getint(); n = getint(); k = getint(); m = getint(); int u, v, w; for (int i = 0; i < m; ++i) { u = getint(); v = getint(); w = getint(); ins(u, v, w); ins(v, u, w); } q = getint(); for (int i = 0; i < q; ++i) { u = getint(); v = getint(); w = getint(); for (int j = v; j <= w; ++j) ban[u][j] = true; } for (int i = 1; i <= d; ++i) for (int j = i; j <= d; ++j) { for (int mt = 1; mt <= n; ++mt) { ava[mt] = true; for (int t = i; t <= j; ++t) if (ban[mt][t]) { ava[mt] = false; break; } } SPFA(); if (dis == INF) cost[i][j] = INF; else cost[i][j] = dis * (j-i+1); } for (int i = 1; i <= d; ++i) { f[i] = cost[1][i]; for (int j = 1; j <= i; ++j) f[i] = min(f[i], f[j] + cost[j+1][i] + k); } printf("%d\n", f[d]); return 0; }
相关文章推荐
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- C#使用动态规划解决0-1背包问题实例分析
- 动态规划
- C++ 动态规划
- DP(动态规划) 解游轮费用问题
- 动态规划的用法——01背包问题
- 动态规划的用法——01背包问题
- 《收集苹果》 动态规划入门
- 《DNA比对》蓝桥杯复赛试题
- 《背包问题》 动态规划
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 关于爬楼梯的动态规划算法
- 动态规划 --- hdu 1003 **
- DP问题各种模型的状态转移方程
- 0-1背包解题过程
- 背包问题
- USACO 3.2.2:Stringsobits
- 字符串编辑距离
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)