1003: [ZJOI2006]物流运输
DP+SPFA
注意边是双向的,以及n,m不能搞反
BZOJ 1003
/**************************************************************
Problem: 1003
User: Dream_Tonight
Language: C++
Result: Accepted
Time:80 ms
Memory:1392 kb
****************************************************************/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair
#define pb push_back
const int maxn = 1e5 + 7;
const int INF = 1e9;
struct node {
int t;
int v;
node(int a, int b) {
t = a;
v = b;
}
};
ll v[105], d[105];
vector<node> ed[1005];
ll f[105], dp[105][105];
vector<int> st[105];
long long spfa(int l, int r, int m) {
queue<int> q;
memset(v, 0, sizeof(v));
for (int i = 1; i <= m; i++) d[i] = INF;
for (int i = l; i <= r; i++) {
for (int j = 0; j < st[i].size(); j++) {
v[st[i][j]] = 1;
}
}
q.push(1);
d[1] = 0;
while (!q.empty()) {
int n = q.front();
q.pop();
for (int i = 0; i < ed[n].size(); i++) {
int tt = ed[n][i].t;
int vv = ed[n][i].v;
if (v[tt] == 0 && d[tt] >= d[n] + vv) {
d[tt] = d[n] + vv;
q.push(tt);
}
}
}
return d[m];
}
int main() {
int n, m, k, e, s, t, p, d;
scanf("%d%d%d%d", &n, &m, &k, &e);
for (int i = 0; i < e; i++) {
scanf("%d%d%d", &s, &t, &p);
ed[s].pb(node(t, p));
ed[t].pb(node(s, p));
}
scanf("%d", &d);
for (int i = 0; i < d; i++) {
scanf("%d%d%d", &p, &s, &t);
for (int j = s; j <= t; j++) {
st[j].push_back(p);
}
}
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
dp[i][j] = spfa(i, j, m);
}
}
f[0] = 0;
for (int i = 1; i <= n; i++) {
f[i] = 1e18;
for (int j = 0; j < i; j++) {
f[i] = min(f[i], f[j] + dp[j + 1][i] * (i - j) + k);
}
}
printf("%lld", f[n] - k);
return 0;
}