• BZOJ 1003 物流运输 (dijkstra & dp)


    物流运输

    1003: [ZJOI2006]物流运输

    给出m(<=20)个点,e条边,从1走到m一共n(<=100)天,但是某一些点会在a~b这段时间里面关闭,所以就要更换落线,每一次更换路线都要消耗权值k,问在n天里从1到m的最小花费。

    首先数据范围是很小的,就可以维护在某一段时间里的最短路。

    那么再定义状态dp[i]表示前前i天所花费的权值。转移方程不难写出f[i] = min(dijkstra(1,i),f[j]+dijkstra(j+1,n)+k).

    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int N = 110;
    const int E = 20010;
    const int inf = 1<<30;
    
    int n,m,k,e,d;
    int f[N],dis[N];
    bool done[N],flag[N][N];
    struct edge{
    	int v,w;
    	edge *nxt;
    }*head[N],*cur,meo[E];
    
    struct node{
    	int dis,u;
    	bool operator < (const node &rhs)const{
    		return dis>rhs.dis;
    	}
    };
    
    void addedge(int u,int v,int w){
    	cur->v = v;
    	cur->w = w;
    	cur->nxt = head[u];
    	head[u] = cur++;
    	
    	cur->v = u;
    	cur->w = w;
    	cur->nxt = head[v];
    	head[v] = cur++;
    }
    
    int dijkstra(int s,int t){
    	priority_queue <node> q;
    	memset(done,false,sizeof(done));
    	for(int i = 1;i <= m;++i)
    	for(int j = s;j <= t;++j){
    		if(flag[i][j]){
    			done[i] = true;
    			break;
    		}
    	}
    	for(int i = 1;i <= m;++i)dis[i] = inf;
    	dis[1] = 0;
    	q.push((node){dis[1],1});
    	while(!q.empty()){
    		node p = q.top();q.pop();
    		int u = p.u;
    		if(done[u])continue;
    		done[u] = true;
    		for(edge *it = head[u];it;it = it->nxt){
    			int v = it->v;
    			if(done[v])continue;
    			if(dis[v] > dis[u]+it->w){
    				dis[v] = dis[u]+it->w;
    				q.push((node){dis[v],v});
    			}
    		}
    	}
    	return (dis[m] == inf) ? dis[m] : dis[m]*(t-s+1);
    }
    
    int main(){
    	cur = meo;
    	ios::sync_with_stdio(false);
    	cin>>n>>m>>k>>e;
    	for(int i = 1;i <= e;++i){
    		int u,v,w;
    		cin>>u>>v>>w;
    		addedge(u,v,w);
    	}
    	cin>>d;
    	for(int i = 1;i <= d;++i){
    		int p,a,b;
    		cin>>p>>a>>b;
    		for(int j = a;j <= b;++j)flag[p][j] = true;
    	}
    	for(int i = 1;i <= n;++i){
    		f[i] = dijkstra(1,i);
    		for(int j = 1;j < i;++j){
    			f[i] = min(f[i],f[j]+dijkstra(j+1,i)+k);
    		}
    	}
    	cout<<f[n]<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    php
    php数据排序---array_multisort
    IOS 线程描述
    IOS 进程描述
    IOS 强指针(strong)和弱指针(weak)
    IOS autosizing(设置控件的固定位置大小)
    IOS UIActivityIndicatorView动画
    IOS UIImageView的帧动画
    IOS Block动画
    IOS UIView动画(封装动画)
  • 原文地址:https://www.cnblogs.com/xgtao984/p/5706766.html
Copyright © 2020-2023  润新知