分析:核心是要计算出任意x天不改变路线所需的花费,即此处的dis[i][j],再用动态规划搞一下就可以了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const int maxn = 105;
const int INF = 1e9;
typedef struct edge
{
int from, to, dist;
edge(int u, int v, int d) :from(u), to(v), dist(d) {}
}edge;
typedef struct heapnode
{
int d, u;
bool operator <(const heapnode& rhs) const {return d > rhs.d;}
}heapnode;
int days,m,K,e;
int avl[maxn][maxn];
int dis[maxn][maxn];
int can[maxn];
int dp[maxn];
typedef struct Dijkstra
{
int n, m;
vector<edge>edges;
vector<int>G[maxn];
bool done[maxn];
int d[maxn];
int p[maxn];
void init(int n)
{
this->n = n;
for(int i=0;i<n;i++) G[i].clear();
edges.clear();
}
void add_edge(int from, int to, int dist)
{
edges.push_back(edge(from, to, dist));
m = edges.size();
G[from].push_back(m - 1);
}
void dijkstra(int s)
{
priority_queue<heapnode>Q;
for(int i=0;i<n;i++) d[i] = INF;
d[s] = 0;
memset(done,0,sizeof(done));
Q.push(heapnode{ 0,s });
while (!Q.empty())
{
heapnode x = Q.top();
Q.pop();
int u = x.u;
if (done[u]) continue;
done[u] = true;
for(int i=0;i<G[u].size();i++)
{
edge &e = edges[G[u][i]];
if (d[e.to] > d[u] + e.dist&&!can[e.to])
{
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push(heapnode{ d[e.to],e.to });
}
}
}
}
}Dijkstra;
Dijkstra D;
Dijkstra *f=&D;
void solve()
{
for(int i=0; i<maxn; i++)
for(int j=0; j<maxn; j++)
dis[i][j]=INF;
for(int i=1; i<=days; i++)
{
for(int j=i; j<=days; j++)
{
memset(can,0,sizeof(can));
for(int k=0; k<m; k++)
for(int g=i; g<=j; g++)
can[k]|=avl[k][g];
f->dijkstra(0);
dis[i][j]=f->d[m-1];
if(dis[i][j]<INF)
dis[i][j]*=(j-i+1);
}
}
}
void DP()
{
for(int i=1;i<=days;i++)
dp[i]=dis[1][i];
for(int i=2;i<=days;i++)
for(int j=1;j<i;j++)
dp[i]=min(dp[i],dp[j]+dis[j+1][i]+K);
}
int main()
{
int u, v, w;
scanf("%d%d%d%d",&days,&m,&K,&e);
f->init(m);
for(int i=0;i<e;i++)
{
scanf("%d%d%d",&u,&v,&w);
u--,v--;
f->add_edge(u,v,w);
f->add_edge(v,u,w);
}
memset(avl,0,sizeof(avl));
int num,st,ed;
scanf("%d",&num);
for(int i=0;i<num;i++)
{
scanf("%d%d%d",&u,&st,&ed);
u--;
for(int j=st;j<=ed;j++)
avl[u][j]=1;
}
solve();
DP();
printf("%d\n",dp[days]);
return 0;
}