P1772 [ZJOI2006]物流运输
Posted zzz-hhh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1772 [ZJOI2006]物流运输相关的知识,希望对你有一定的参考价值。
思路:
那么思考怎么构建(dp)方程
首先我们可以设(f[i])表示前(i)天所花费的最小值
(f[i] = min( f[i],f[j-1]+(i-j+1) ast L+K) (1 leq j leq i))
什么意思呢 ?
就是第(j)天到第(i)天走同一条路,并且这条路和第(j-1)天是不同的
L就是这一天把,l到r天之内不能走的点都去掉,然后跑一边dijkstra
求一下1到m点的最短路,然后跑一下DP式子.
代码中有详解.
code
#include <bits/stdc++.h>
#include <queue>
#define N 100010
#define M 110
using namespace std;
int n, m, e, k, d;
int head[N << 1], add_edge, f[M], dis[M]; bool vis[M];
map<int, bool> ma[M];
struct node {
int next, to, dis;
}edge[N << 1];
struct OOO {//堆优化dijkstra用品
int po, dis;
bool operator < (const OOO &b) const {
return dis > b.dis;
}
};
int read() {
int s = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
return f ? -s : s;
}
void add(int from, int to, int dis) {//这就是一个很普通的前向星建图
edge[++add_edge].next = head[from];
edge[add_edge].to = to;
edge[add_edge].dis = dis;
head[from] = add_edge;
}
void dijkstra() {//很普通的堆优化dijkstra
priority_queue<OOO> q;
q.push((OOO){1, 0});
dis[1] = 0;
while (!q.empty()) {
OOO fr = q.top(); q.pop();
int x = fr.po;
for (int i = head[x]; i; i = edge[i].next) {
int to = edge[i].to;
if (!vis[to] && dis[to] > dis[x] + edge[i].dis) {
dis[to] = dis[x] + edge[i].dis;
q.push((OOO){to, dis[to]});
}
}
}
}
void init(int l) {
for (int j = 1; j <= m; j++)//判断那个点在这个区间内不能走,然后vis表示访问过了.
if (ma[j][l]) vis[j] = 1;
memset(dis, 0x3f, sizeof(dis));//dijkstra用物
}
int main() {
n = read(), m = read(), k = read(), e = read();
for (int i = 1, x, y, de; i <= e; i++) {
x = read(), y = read(), de = read();
add(x, y, de), add(y, x, de);
}
d = read();
for (int i = 1, dat, l, r; i <= d; i++) {
dat = read(), l = read(), r = read();
for (int j = l; j <= r; j++)
ma[dat][j] = 1;//用map存一下是不是停运的马头
}
int ans = 0;
memset(f, 0x3f, sizeof(f));//dp用物
f[0] = -k;
for (int i = 1; i <= n; i++) {
memset(vis, 0, sizeof(vis));//不清空,火葬场。
for (int j = i; j >= 1; j--) {
init(j);
dijkstra();
int x = dis[m];
if (x == 0x3f3f3f3f) break;
f[i] = min(f[i], f[j - 1] + (i - j + 1) * x + k);//很简单的DP
}
}
cout << f[n];
return 0;
}
以上是关于P1772 [ZJOI2006]物流运输的主要内容,如果未能解决你的问题,请参考以下文章