• [ZJOI2006][线性DP][最短路] 物流运输


    题面


    (DP) + 最短路

    外层可以看成是一个线性 (DP),就是枚举一下分割点,表示这一个区间内的路线相同,要求总价值最小。
    内层我们需要计算一下一个区间的价值,其实就是跑一个最短路就行了。
    对于不合法的路线跑最短路时标记出来不使用即可。

    代码:

    # include <iostream>
    # include <cstdio>
    # include <queue>
    # include <cstring>
    # define MAXN 105
    # define MAXM 25
    # define MAXE 5005
    
    struct edge{
    	int v, next, w;
    }e[MAXE<<1]; int hd[MAXN], cntE;
    bool unava[MAXN][MAXM], cant[MAXM];
    int dis[MAXM]; bool inQ[MAXM];
    int f[MAXN];
    
    void AddE(int u, int v, int w){
    	e[++cntE] = (edge){v, hd[u], w};
    	hd[u] = cntE;
    }
    
    int SPFA(int from, int to){
    	memset(dis, 0x3f, sizeof(dis));
    	std::queue<int>Q;
    	Q.push(from); dis[from] = 0;
    
    	while(Q.size()){
    		int now = Q.front(); Q.pop();
    		inQ[now] = 0;
    
    		for(int i = hd[now]; i; i = e[i].next){
    			if(!cant[e[i].v]){
    				if(dis[e[i].v] > dis[now] + e[i].w){
    					dis[e[i].v] = dis[now] + e[i].w;
    					if(!inQ[e[i].v]){
    						Q.push(e[i].v);
    						inQ[e[i].v] = 1;
    					}
    				}
    			}
    		}
    	}
    
    	return dis[to];
    }
    
    int main(){
    	int n, m, K, e, d;
    
    	scanf("%d%d%d%d", &n, &m, &K, &e);
    
    	for(int i = 1, u, v, w; i <= e; i++){
    		scanf("%d%d%d", &u, &v, &w);
    		AddE(u, v, w); AddE(v, u, w);
    	}
    
    	scanf("%d", &d);
    
    	for(int i = 1, p, a, b; i <= d; i++){
    		scanf("%d%d%d", &p, &a, &b);
    		for(int j= a; j <= b; j++){
    			unava[j][p] = 1;
    		}
    	}
    
    	memset(f, 0x3f, sizeof(f));
    	f[0] = -K; // 细节,第一次选择的路线不算修改的路线
    	for(int i = 1; i <= n; i++){
    		memset(cant, 0, sizeof(cant));
    		for(int j = i, tmp; j >= 1; j--){
    			for(int k = 1; k <= m; k++){
    				if(unava[j][k]){
    					cant[k] = 1;
    				}
    			}
    
    			tmp = SPFA(1, m);
    			// printf("%d
    ", tmp);
    
    			if(tmp == 0x3f3f3f3f){
    				break;
    			}
    
    			f[i] = std::min(f[i], f[j-1]+(i-j+1)*tmp+K);
    		}
    	}
    
    	printf("%d", f[n]);
    
    	return 0;
    }
    
  • 相关阅读:
    [ Python ] 递归函数
    [ Python ] 计算器
    [ Python ] 模块详解
    [ python ] 项目:haproxy配置文件增删改查
    [ Python ] 装饰器详解
    iOS设计
    Swift
    Swift
    iOS
    Swift
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13726022.html
Copyright © 2020-2023  润新知