Question meaning: Give a picture, let you run n shortest paths, the first shortest paths have a number of points can not be used, and change a route will need to add k additional costs, ask after running n minimum costs.
Train of Thought: The starting point is that the cost is unchanged in a certain period of time, changing the route will cost more, and naturally think of dp. So when we think of dividing the n-th shortest path into the sum of the shortest paths in several intervals, we can pretreat each shortest path, because only the n*n interval has a maximum of 100. Let dp[i][j] denote the minimum of all costs for the shortest paths from the first to the third. So the answer is dp[1][n].
Interval dp is the way to write a routine. The first dimension enumerates the length of the interval, the second dimension enumerates the starting point, and the third dimension enumerates the middle point.
The shortest path in a preprocessing period is to check whether a point is available before adding relaxation.
(n and m are silly and confused, wa a few more)
#include<bits/stdc++.h> using namespace std; const int maxn=200; const int maxm=1000; int cnt=-1,n,m,k,e; int head[maxn],use[110][110],dist[maxn],dp[110][110]; bool inq[maxn]; struct Edge { int nex; int to,w; } edge[maxm]; void add_edge(int u,int v,int w) { edge[++cnt].nex=head[u]; edge[cnt].to=v; edge[cnt].w=w; head[u]=cnt; } bool check(int x,int s,int t) { for(int i=s; i<=t; i++) if(!use[x][i]) return false; return true; } int spfa(int s,int t) { memset(dist,0x3f,sizeof(dist)); memset(inq,false,sizeof(inq)); queue<int>que; while(!que.empty()) que.pop(); que.push(1); dist[1]=0; inq[1]=true; while(!que.empty()) { int u=que.front(); que.pop(); inq[u]=false; for(int i=head[u]; i!=-1; i=edge[i].nex) { int v=edge[i].to; if(check(v,s,t)&&dist[v]>dist[u]+edge[i].w) { dist[v]=dist[u]+edge[i].w; if(!inq[v]) inq[v]=true,que.push(v); } } } return dist[m]==0x3f3f3f3f ? 0x3f3f3f3f:dist[m]*(t-s+1); } void solve() { for(int i=1; i<=n; i++) { for(int j=i; j<=n; j++) dp[i][j]=spfa(i,j); } int e; for(int len=2; len<=n; len++) for(int s=1; (e=s+len-1)<=n; s++) for(int p=s; p<s+len-1; p++) { dp[s][e]=min(dp[s][e],dp[s][p]+dp[p+1][e]+k); } printf("%d\n",dp[1][n]); } int main() { while(~scanf("%d %d %d %d",&n,&m,&k,&e)) { memset(head,-1,sizeof(head)); cnt=-1; for(int i=1;i<maxm;i++) edge[i].nex=-1; for(int i=1; i<=e; i++) { int a,b,c; scanf("%d %d %d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } memset(use,1,sizeof(use)); int tem; scanf("%d",&tem); for(int i=1; i<=tem; i++) { int p,a,b; scanf("%d %d %d",&p,&a,&b); for(int j=a; j<=b; j++) use[p][j]=0; } solve(); } }