真是喜闻乐见地做了两天,SPFA+DP,把一个本来如果按照天数来看是动态的东西变成静态的,因为花费最少肯定使一个最短路,这样就可以SPFA了,用一个前缀和来判断是否在这段时间内都能通,这样就可以直接上DP了
f[i]=f[j]+cost[j][i]*(i-j)+K
/************************************************************** Problem: 1003 User: BPM136 Language: C++ Result: Accepted Time:28 ms Memory:1376 kb ****************************************************************/ #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<bitset> #include<algorithm> #define LL long long #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std; inline LL read() { LL d=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } #define M 105 #define N 25 /* struct edge { int y,w,next; }e[N*M]; int last[N],ne=0; */ bool c[N][M]; int f[M],cost[M][M]; int ch[N][N]; int K,n,m,d; /* void add(int u,int v,int w) { e[++ne].y=v;e[ne].w=w;e[ne].next=last[u];last[u]=ne; } void add2(int x,int y,int w) { add(x,y,w);add(y,x,w); } */ int sum[N][M]; int q[10005],dis[N]; bitset<N>inq; int SPFA(int be,int en) { inq.reset();memset(dis,127/2,sizeof(dis)); int h=0,t=1; q[1]=1;dis[1]=0; while(h<t) { int now=q[++h]; inq[now]=0; // efo(i,now) // if(dis[now]+e[i].w<dis[e[i].y]&&sum[e[i].y][en]==sum[e[i].y][be]) fo(i,1,n) if(ch[now][i]!=0&&sum[i][be]==sum[i][en]) if(dis[now]+ch[now][i]<dis[i]) { dis[i]=dis[now]+ch[now][i]; if(inq[i]==0) { inq[i]=1; q[++t]=i; } } } return dis[n]; } void prework() { fo(i,1,n) { sum[i][0]=0; fo(j,1,m) { sum[i][j]=sum[i][j-1]+c[i][j]; } } fo(i,1,d) { fo(j,0,i-1) { cost[j][i]=SPFA(j,i); // cout<<j<<' '<<i<<' '<<cost[j][i]<<endl; } } } void DP() { memset(f,127/3,sizeof(f)); f[0]=0; fo(i,1,d) { fo(j,0,i-1) if(cost[j][i]<1000000) { f[i]=min(f[i],f[j]+cost[j][i]*(i-j)+K); } } } int main() { d=read(),n=read(),K=read(),m=read(); fo(i,1,m) { int x=read(),y=read(),w=read(); if(ch[x][y]==0||ch[x][y]>w) { ch[x][y]=w; ch[y][x]=w; } } memset(c,0,sizeof(c)); int t=read(); while(t--) { int x=read(),be=read(),en=read(); fo(i,be,en) c[x][i]=1; } prework(); DP(); cout<<f[d]-K<<endl; return 0; }