BZOJ1003
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #include<vector> #define maxn 3005 #define rint register int #define ll long long #define int unsigned long long #define inf 0x77777777777777f #define pb push_back #define mod (int)1e9 + 7 using namespace std; inline int read() { char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void write(int x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return ; } int n, m, K, e, dp[maxn]; int d, stop[maxn][maxn], cost[maxn][maxn]; //cost[i][j]表示第i到j天不变路线的单次最少花费 int dis[maxn], vis[maxn], no[maxn]; queue<int> q; int head[maxn], nex[maxn], to[maxn], val[maxn], total; inline void add(int a, int b, int c) { to[++total] = b, nex[total] = head[a], head[a] = total, val[total] = c; return ; } inline int spfa(int x, int y) { memset(dis, 0x3f, sizeof(dis)), memset(vis, 0, sizeof(vis)), memset(no, 0, sizeof(no)); for (rint i = 1; i <= m; ++i) for (rint j = x; j <= y; ++j) if (stop[i][j]) no[i] = 1; dis[1] = 0, vis[1] = 1, q.push(1); while (!q.empty()) { int u = q.front(); q.pop(); for (rint e = head[u]; e; e = nex[e]) { int v = to[e]; if (!no[v] && dis[v] > dis[u] + val[e]) { dis[v] = dis[u] + val[e]; if (!vis[v]) { vis[v] = 1; q.push(v); } } } vis[u] = 0; } return dis[m]; } signed main() { n = read(), m = read(), K = read(), e = read(); for (rint i = 1; i <= e; ++i) { int x = read(), y = read(), z = read(); add(x, y, z), add(y, x, z); } d = read(); for (rint i = 1; i <= d; ++i) { int p = read(), a = read(), b = read(); for (rint i = a; i <= b; ++i) stop[p][i] = 1;//stop[i][j]表示第i点j天不开 } for (rint i = 1; i <= n; ++i) for (rint j = i; j <= n; ++j) cost[i][j] = spfa(i, j); memset(dp, 0x3f, sizeof(dp)); dp[0] = 0; for (rint i = 1; i <= n; ++i) for (rint j = 1; j <= i; ++j) dp[i] = min(dp[i], dp[j - 1] + K + cost[j][i] * (i - j + 1)); write(dp[n] - K);//最后-k因为j=1时没变,dp却+了k return 0; }