BZOJ 1003 [ZJOI2006]物流运输trans SPFA+DP

题意:链接方法:SPFA+DP解析:挺好的题目,,由于数据范围较小所以用这种方式可以搞,不过也是挺不好想的。我们定义cost(i,j)表示从第i天走到第j天运用同一种方式的最小花费,然后由于数据比较小,我们定义f[i]表示前i天的最小花费。接下来我们就可以写出来转移方程了j比i小。然后就可以水过了!顺带提一下,在计算cost(j+1,i)时,要考虑每个限制区段的预处理,也就是哪些点在这些天中均可走。代码:;int n,m,K,e,d,cnt;int v[N],can[N],f[N];struct node{int to;int next;int val;}edge[M];int head[N],dis[N];struct limit{int p,a,b;}l[M];//f[i]=max(c(1,i),f[j]+k+c(j+1,i));void init(){memset(head,-1,sizeof(head));cnt=1;}void edgeadd(int from,int to,int val){edge[cnt].to=to;edge[cnt].val=val;edge[cnt].next=head[from];head[from]=cnt++;}int cost(int le,int ri){memset(can,0,sizeof(can));for(int i=1;i<=d;i++){if(max(le,l[i].a)<=min(ri,l[i].b))can[l[i].p]=1;}memset(dis,0x3f,sizeof(dis));memset(v,0,sizeof(v));queue<int>q;q.push(1);v[1]=1;dis[1]=0;while(!q.empty()){int u=q.front();q.pop();v[u]=0;for(int i=head[u];i!=-1;i=edge[i].next){int to=edge[i].to;if(can[to])continue;if(dis[u]+edge[i].val<dis[to]){dis[to]=dis[u]+edge[i].val;if(!v[to]){q.push(to);v[to]=1;}}}}if(dis[m]==INF)return INF;return dis[m]*(ri-le+1);}int main(){init();scanf(“%d%d%d%d”,&n,&m,&K,&e);for(int i=1;i<=e;i++){int x,y,z;scanf(“%d%d%d”,&x,&y,&z);edgeadd(x,y,z);edgeadd(y,x,z);}scanf(“%d”,&d);for(int i=1;i<=d;i++)scanf(“%d%d%d”,&l[i].p,&l[i].a,&l[i].b);for(int i=1;i<=n;i++){f[i]=cost(1,i);for(int j=1;j<i;j++){f[i]=min(f[i],f[j]+K+cost(j+1,i));}}printf(“%d\n”,f[n]);}

即使爬到最高的山上,一次也只能脚踏实地地迈一步。

BZOJ 1003 [ZJOI2006]物流运输trans SPFA+DP

相关文章:

你感兴趣的文章:

标签云: