数据出奇的小,于是想到了暴力。
F[i]表示前i天的最小话费
得到转移方程式f[i]=sigma(f[j]+cost(j+1,i)*(i-j))(j<i)
其中cost(I,j)可以用spfa实现
这样就可以ac了
时间:O(N^2{dp}*kE{spfa})
PS:这是#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int f[105],mp[25][25],ok[25][105];
int q[1005],vis[25],dis[25],fl[25];
int n,m,k,p,x,y,z;
int spfa(int S,int T){
memset(dis,1,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(fl,0,sizeof(fl));
for (int i=S;i<=T;i++)
for (int j=1;j<=m;j++)
fl[j]|=ok[j][i];
if (fl[1]||fl[m]) return 1e8;
int h=0,t=1;
q[1]=1; dis[1]=0; vis[1]=1;
while (h<t){
int x=q[++h];
vis[x]=0;
for (int i=1;i<=m;i++)
if (!fl[i]&&dis[i]>dis[x]+mp[x][i]){
dis[i]=dis[x]+mp[x][i];
if (!vis[i]){
vis[i]=1;
q[++t]=i;
}
}
}
return dis[m];
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&p);
memset(mp,1,sizeof(mp));
for (int i=1;i<=p;i++){
scanf("%d%d%d",&x,&y,&z);
mp[x][y]=mp[y][x]=z;
}
scanf("%d",&p);
for (int i=1;i<=p;i++){
scanf("%d%d%d",&x,&y,&z);
for (int j=y;j<=z;j++) ok[x][j]=1;
}
memset(f,1,sizeof(f));
f[0]=-k;
for (int i=1;i<=n;i++)
for (int j=0;j<i;j++)
f[i]=min(f[i],f[j]+spfa(j+1,i)*(i-j)+k);
printf("%d",f[n]);
}