【链接】
bzoj1003
【解题报告】
定义 gi,j 表示 i ~ j 这段时间的最短路径。
fi 表示第 i 的总成本。
可以得转移方程 fi=fj+K+gj+1,i∗(i−j)
#include
#include
#include
#define LL long long
using namespace std;
const int maxn=105,maxm=805,maxv=25;
int T,n,P,m,D,tot,g[maxn][maxn],que[maxn],dst[maxn],lnk[maxn],son[maxm],nxt[maxm],w[maxm];
bool vis[maxn],pd[maxn],flg[maxn][maxv];
LL f[maxn];
inline char nc()
{
static char buf[100000],*l,*r;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
if (l==r) return EOF; return *l++;
}
inline int Read()
{
int res=0; char ch=nc();
while (ch<'0'||ch>'9') ch=nc();
while (ch>='0'&&ch<='9') res=res*10+ch-48,ch=nc();
return res;
}
void Add(int x,int y,int z) {w[++tot]=z; son[tot]=y; nxt[tot]=lnk[x]; lnk[x]=tot;}
int Spfa(int s,int t)
{
memset(dst,63,sizeof(dst));
memset(pd,1,sizeof(pd));
memset(vis,0,sizeof(vis));
for (int i=s; i<=t; i++)
for (int j=1; j<=n; j++)
if (!flg[i][j]) pd[j]=0;
int hed=0,til=1; que[1]=1; dst[1]=0; vis[1]=1;
while (hed!=til)
{
int x=que[hed=(hed+1)%maxn]; vis[x]=0;
for (int j=lnk[x]; j; j=nxt[j])
if (pd[son[j]]&&dst[x]+w[j]<=dst[son[j]])
{
dst[son[j]]=dst[x]+w[j];
if (!vis[son[j]])
{
vis[son[j]]=1; que[til=(til+1)%maxn]=son[j];
if (dst[que[til]]1)%maxn]]) swap(que[til],que[(hed+1)%maxn]);
}
}
}
return dst[n];
}
int main()
{
freopen("1003.in","r",stdin);
freopen("1003.out","w",stdout);
T=Read(); n=Read(); P=Read(); m=Read(); tot=0;
for (int i=1,x,y,z; i<=m; i++) x=Read(),y=Read(),z=Read(),Add(x,y,z),Add(y,x,z);
D=Read(); memset(flg,1,sizeof(flg));
for (int i=1; i<=D; i++)
{
int x=Read(),s=Read(),t=Read();
for (int j=s; j<=t; j++) flg[j][x]=0;
}
for (int i=1; i<=T; i++)
for (int j=1; j<=T; j++) g[i][j]=Spfa(i,j);
for (int i=1; i<=T; i++)
{
f[i]=(LL)g[1][i]*i;
for (int j=1; j1][i]*(i-j));
}
printf("%lld\n",f[T]);
return 0;
}