预处理cost[a][b] 表示第a天到第b天用同一条线路的成本。
具体转移看代码。
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; #define N 21 typedef long long ll; #define M 401 int n,m,K,day; int v[M<<1],first[N],next[M<<1],w[M<<1],en,cost[101][101],f[101]; bool cant[N][101][101]; void AddEdge(int U,int V,int W) { v[++en]=V; w[en]=W; next[en]=first[U]; first[U]=en; } queue<int>q; bool inq[N]; int dis[N]; void spfa(int from,int to) { memset(inq+1,0,sizeof(bool)*n); memset(dis+1,0x7f,sizeof(int)*n); q.push(1); inq[1]=1; dis[1]=0; while(!q.empty()) { int U=q.front(); for(int i=first[U];i;i=next[i]) if((!cant[v[i]][from][to])&&(ll)dis[v[i]]>(ll)dis[U]+(ll)w[i]) { dis[v[i]]=dis[U]+w[i]; if(!inq[v[i]]) { q.push(v[i]); inq[v[i]]=1; } } q.pop(); inq[U]=0; } } int main() { int x,y,z,P; scanf("%d%d%d%d",&day,&n,&K,&m); for(int i=1;i<=m;++i) { scanf("%d%d%d",&x,&y,&z); AddEdge(x,y,z); AddEdge(y,x,z); } scanf("%d",&P); for(;P;--P) { scanf("%d%d%d",&x,&y,&z); for(int i=1;i<=z;++i) for(int j=max(y,i);j<=day;++j) cant[x][i][j]=1; } for(int i=1;i<=day;++i) for(int j=i;j<=day;++j) { spfa(i,j); cost[i][j]=dis[n]*(dis[n]>2000000000?1:(j-i+1)); } memset(f+1,0x7f,sizeof(int)*day); for(int i=0;i<=day;++i) for(int j=i+1;j<=day;++j) f[j]=(int)min((ll)f[j],(ll)f[i]+(ll)(i==0?0:K)+(ll)cost[i+1][j]); printf("%d\n",f[day]); return 0; }
时间: 2024-10-16 18:41:16