(Ps:好开心好开心自己写对了一道提高+的洛谷题)
首先第一秒想到了今年提高的d1t3(后遗症)
然后开始考虑dp果然有思路:
1,用f[i][j]表示前i天换j次所用的最小时间(不包括换的时间),dis[x]表示到x的最短路径
2,考虑转移:
首先设从第k(1<=k<=i)天到第i天起路线相同,
显然f[i][j]=max(f[i][j],f[k][k-1]+dis[m]*(i-k));
此时从后往前扫,每次把不能用的点加入到flag1里,每次写一个spfa来更新dis
最终答案为max(f[n][i]);(0<=i<n);
时间复杂度大概是O(N^2*(N+E*K));
首先第一秒想到了今年提高的d1t3(后遗症)
然后开始考虑dp果然有思路:
1,用f[i][j]表示前i天换j次所用的最小时间(不包括换的时间),dis[x]表示到x的最短路径
2,考虑转移:
首先设从第k(1<=k<=i)天到第i天起路线相同,
显然f[i][j]=max(f[i][j],f[k][k-1]+dis[m]*(i-k));
此时从后往前扫,每次把不能用的点加入到flag1里,每次写一个spfa来更新dis
最终答案为max(f[n][i]);(0<=i<n);
时间复杂度大概是O(N^2*(N+E*K));
我用的是spfa求所以是K*E,如果用迪杰斯特拉应该会快点(M^2)(还有堆优化)
献上蒟蒻的ac代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int N=110,M=22;
int n,m,K,e,f[N][N],dis[M],flag[M],b[M],c[N][M],tot,flag1[M];
int inf,ans;
struct node { int from,to,last,val; }a[M*M*2];
queue<int>q;
void add(int x,int y,int v)
{
a[++tot].from=x;
a[tot].to=y;
a[tot].last=b[x];
a[tot].val=v;
b[x]=tot;
}
void spfa()
{
int i,j,k;
memset(dis,0x3f,sizeof(dis));
inf=dis[1];q.push(1);dis[1]=0;
while(!q.empty())
{
j=q.front();flag[j]=0;
for(i=b[j];i;i=a[i].last)
if(!flag1[a[i].to])
{
if(dis[a[i].to]>(dis[j]+a[i].val))
{
dis[a[i].to]=dis[j]+a[i].val;
if(!flag[a[i].to]) flag[a[i].to]=1,q.push(a[i].to);
}
}
q.pop();
}
}
int main()
{
freopen("csy.in","r",stdin);
freopen("csy.out","w",stdout);
int i,j,k,v,l,r,k1;
scanf("%d%d%d%d",&n,&m,&K,&e);
memset(f,0x3f,sizeof(f));
f[0][0]=0;
for(i=1;i<=e;++i)
{
scanf("%d%d%d",&j,&k,&v);
add(j,k,v);add(k,j,v);
}
scanf("%d",&j);
for(i=1;i<=j;++i)
{
scanf("%d%d%d",&k,&l,&r);
for(k1=l;k1<=r;++k1)
c[k1][k]=1;
}
for(i=1;i<=n;++i)
{
memset(flag1,0,sizeof(flag1));
for(j=i;j>=1;--j)
{
for(k=1;k<=m;++k)
flag1[k]=max(c[j][k],flag1[k]);
spfa();
if(dis[m]!=inf)
for(k=1;k<i;++k)
f[i][k]=min(f[j-1][k-1]+dis[m]*(i-j+1),f[i][k]);
else break;
}
if(dis[m]!=inf)
f[i][0]=dis[m]*i;
}
ans=inf;
for(j=0;j<n;++j)
if(f[n][j]<inf)
ans=min(ans,f[n][j]+j*K);
printf("%d\n",ans);
return 0;
}