题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1003
思路:m个点e条边n天。给出每条边的权值以及有些点有些天不能走。对于某连续的两天i和i+1,若两天从起点到终点选择的路径不同需要额外代价K。求最小的总代价:ans=sum(每天的代价)+K*改变的次数。每天的代价定义为这一天s到t选择的路径的长度。
思路:令cost[i][j]表示从第i天 到第j天选择一条路径的最短路,f[i]表示前i天的总代价,则f[i]=min(f[j]+cost[j+1][i]*(i-j)+K)。计算 cost[i][j]直接枚举i和j计算最短路。这里有些点可能[i,j]天不能走,而且[p,q]天也不能走。不是说只有一段时间不能走。每次求最短路 时只能利用能走的点进行转移。
vector<pair<int,int> > g[N]; int n,m,K,e,d; int node[N],L[N],R[N]; int ok[N]; int cal(int x,int y) { queue<int> Q; int dis[N],h[N],i,u,v,w; clr(ok,0); FOR0(i,d) { u=node[i]; if(x>R[i]||y<L[i]); else ok[u]=1; } FOR1(i,m) dis[i]=INF; clr(h,0); dis[1]=0; Q.push(1); while(!Q.empty()) { u=Q.front(); Q.pop(); h[u]=0; FOR0(i,SZ(g[u])) { v=g[u][i].first; w=g[u][i].second; if(!ok[v]&&dis[v]>dis[u]+w) { dis[v]=dis[u]+w; if(!h[v]) Q.push(v),h[v]=1; } } } return dis[m]; } int f[N],cost[N][N]; int main() { RD(n,m); RD(K,e); clr(L,-1); int i,j,u,v,w; FOR0(i,e) { RD(u,v,w); g[u].pb(MP(v,w)); g[v].pb(MP(u,w)); } RD(d); FOR0(i,d) RD(node[i],L[i],R[i]); FOR1(i,n) for(j=i;j<=n;j++) cost[i][j]=cal(i,j); for(i=1;i<=n;i++) { f[i]=INF; for(j=0;j<i;j++) if(f[j]!=INF&&cost[j+1][i]!=INF) { if(j==0) w=0; else w=K; f[i]=min(f[i],f[j]+cost[j+1][i]*(i-j)+w); } } PR(f[n]); return 0; }
BZOJ 1003 物流运输trans(最短路),布布扣,bubuko.com
原文地址:http://www.cnblogs.com/jianglangcaijin/p/3799590.html