最短路+dp。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxd 150 #define maxv 250 #define maxe 50050 #define inf 1000000007 using namespace std; struct edge { long long v,w,nxt; }e[maxe]; long long d,n,k,m,qq,g[maxv],nume=0,dis[maxv],dp[maxv],x,y,z,t[maxd][maxd]; bool lim[maxd][maxv],vis[maxv],block[maxv]; queue <long long> q; void addedge(long long u,long long v,long long w) { e[++nume].v=v; e[nume].w=w; e[nume].nxt=g[u]; g[u]=nume; } void reset(long long x,long long y) { memset(block,true,sizeof(block)); fill(dis+1,dis+n+1,inf); memset(vis,false,sizeof(vis)); while (!q.empty()) q.pop(); for (long long i=x;i<=y;i++) for (long long j=1;j<=n;j++) { if (!lim[i][j]) block[j]=false; } } long long spfa(long long x,long long y) { reset(x,y); q.push(1);dis[1]=0;vis[1]=true; while (!q.empty()) { long long head=q.front();q.pop(); for (long long i=g[head];i;i=e[i].nxt) { long long v=e[i].v; if ((block[v]) && (dis[v]>dis[head]+e[i].w)) { dis[v]=dis[head]+e[i].w; if (!vis[v]) { vis[v]=true; q.push(v); } } } vis[head]=false; } return dis[n]; } void dpp() { for (long long i=1;i<=d;i++) { dp[i]=t[1][i]*i; for (long long j=0;j<i;j++) dp[i]=min(dp[i],dp[j]+k+(i-j)*t[j+1][i]); } } int main() { memset(g,0,sizeof(g)); memset(lim,true,sizeof(lim)); scanf("%lld%lld%lld%lld",&d,&n,&k,&m); for (long long i=1;i<=m;i++) { scanf("%lld%lld%lld",&x,&y,&z); addedge(x,y,z); addedge(y,x,z); } scanf("%lld",&qq); for (long long i=1;i<=qq;i++) { scanf("%lld%lld%lld",&x,&y,&z); for (long long j=y;j<=z;j++) lim[j][x]=false; } for (long long i=1;i<=d;i++) for (long long j=i;j<=d;j++) t[i][j]=spfa(i,j); dpp(); printf("%lld\n",dp[d]); return 0; }