SPFA预处理road
f[i]表示前i天的最小成本
emmmm……dp方程是看题解的
一看dp就怂
#include<cstdio>
#include<cstring>
int len=0,can[1100];
struct nod1{int x,y,c,next;}a[1100];
struct nod2{int v=0,s=999999999;}b[1100];
long long road[1010][1010],f[1000100];
int n,m,e,k,d,first[1010],t[1010][1010];
//空间不要开太大!第一次RE就是因为这个。。。
long long minn(long long x,long long y)
{
//一直跑不出样例就是因为这里的long long 都打成了int。。。又是一个教训
return x<y?x:y;
}
int ins(int x,int y,int c)
{
len++;
a[len].x=x;
a[len].y=y;
a[len].c=c;
a[len].next=first[x];
first[x]=len;
}
int spfa(int l,int r)
{
memset(can,0,sizeof(can));
for(int i=1;i<=n;i++)
{//这里!!!让我WA了好几次90
//就是因为for i-m for 成了1-n
//=-=。。。
b[i].s=999999999;
b[i].v=0;
}
int tou=1,wei=2;
f[1]=1;
b[1].s=0;
b[1].v=1;
for(int i=l;i<=r;i++)
{
for(int j=1;j<=m;j++)
{
if(t[i][j])can[j]=1;
}//通不通
}
while(tou<wei)
{
int x=f[tou];
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if((can[y]!=1)&&b[y].s>b[x].s+a[i].c)
{
b[y].s=b[x].s+a[i].c;
if(b[y].v==0)
{
b[y].v=1;
f[wei]=y;
wei++;
}
}
}
tou++;
b[x].v=0;
}
return b[m].s;
}
void work()
{
for(int i=1;i<=n;i++)
{
f[i]=(long long)road[1][i]*i;
for(int j=1;j<i;j++)
{//这里有点神奇
//好像for 0~i-1 和1~i-1 都可以。。。好像2开始也可以。。。
f[i]=minn(f[i],f[j]+road[j+1][i]*(i-j)+k);
}
//printf("%d",f[i]);
}
}
int main()
{
scanf("%d %d %d %d",&n,&m,&k,&e);
for(int i=1;i<=e;i++)
{
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
ins(x,y,z);ins(y,x,z);
}
scanf("%d",&d);
for(int i=1;i<=d;i++)
{
int x,l,r;
scanf("%d %d %d",&x,&l,&r);
for(int j=l;j<=r;j++)
{
t[j][x]=1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
road[i][j]=spfa(i,j);
//printf("%d\n",road[i][j]);
}
}
work();
printf("%d",f[n]);
}