1003: [ZJOI2006]物流运输trans
spfa+dp;
刚刚开始一直想不通怎么判断他是否换了道;
后来才知道,将那个时间段打包,找出这段时间内的最短路;
真是太奇妙了!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define inf 1e6 using namespace std; int map[22][22]; int pass[22][105]; int d[22],inq[22]; int n,m,k,e; int dp[22]; int spfa(int s,int t) { queue<int>q; for(int i=1; i<=m; i++) { d[i]=inf; inq[i]=0; } d[1]=0; q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); inq[u]=0; for(int i=1; i<=m; i++) { if(map[u][i]&&(pass[i][t]==pass[i][s])&&(d[i]>d[u]+map[u][i])) { d[i]=d[u]+map[u][i]; if(!inq[i]) { inq[i]=1; q.push(i); } } } } return d[m]; } int main() { int a,b,c,p; scanf("%d%d%d%d",&n,&m,&k,&e); while(e--) { scanf("%d%d%d",&a,&b,&c); if(map[a][b]==0||map[a][b]>c) map[a][b]=map[b][a]=c; } scanf("%d",&p); while(p--) { scanf("%d%d%d",&a,&b,&c); for(int i=b; i<=c; i++) pass[a][i]=1; } for(int i=1; i<=m; i++) for(int j=1; j<=n; j++) pass[i][j]=pass[i][j-1]+pass[i][j]; for(int i=1; i<=n; i++) { dp[i]=inf; for(int j=0; j<i; j++) dp[i]=min(dp[i],dp[j]+spfa(j,i)*(i-j)+k); } printf("%d\n",dp[n]-k); return 0; }