BZOJ 1003 物流运输【最短路】【动态规划】
这道题数据太小啦!先枚举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):
#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[n] == INF) cost[i][j] = INF; else cost[i][j] = dis[n] * (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; }