zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    poj 2485 Highways 最小生成树
    hdu 3415 Max Sum of MaxKsubsequence
    poj 3026 Borg Maze
    poj 2823 Sliding Window 单调队列
    poj 1258 AgriNet
    hdu 1045 Fire Net (二分图匹配)
    poj 1789 Truck History MST(最小生成树)
    fafu 1181 割点
    减肥瘦身健康秘方
    人生的问题
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13726022.html
Copyright © 2011-2022 走看看