zoukankan      html  css  js  c++  java
  • 【BZOJ1003】[ZJOI2006]物流运输

    【BZOJ1003】[ZJOI2006]物流运输

    题面

    洛谷

    bzoj

    题解

    (f_i)表示前(i)天花费的最小值。

    我们设第(l,r)(1)(m)的距离为(dis_{l,r}),这个可以(n^2)遍最短路求出。

    那么转移就很显然了:

    [f_i=min_{j=0}^{i-1} f_j+dis_{j+1,i} imes (i-j)+K ]

    注意初值(f_0=-K),因为第一次更改不算贡献。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring> 
    #include <cmath> 
    #include <algorithm>
    #include <queue> 
    using namespace std; 
    const int MAX_N = 1e3 + 5; 
    struct Graph { int to, cost, next; } e[MAX_N << 1]; 
    int fir[MAX_N], e_cnt; 
    void Add_Edge(int u, int v, int w) {
    	e[e_cnt] = (Graph){v, w, fir[u]};
    	fir[u] = e_cnt++; 
    }
    const int INF = 1e9; 
    int N, M, K, E, D; 
    bool run[MAX_N][MAX_N], ok[MAX_N], inq[MAX_N];
    int dis[MAX_N][MAX_N], ds[MAX_N]; 
    void spfa(int l, int r) {
    	for (int i = 1; i <= M; i++) {
    		ok[i] = 1;
    		for (int j = l; j <= r && ok[i]; j++) if (run[i][j]) ok[i] = 0; 
    	} 
    	queue<int> que;
    	for (int i = 1; i <= M; i++) ds[i] = INF, inq[i] = 0; 
    	ds[1] = 0, inq[1] = 1, que.push(1); 
    	while (!que.empty()) { 
    		int x = que.front(); que.pop(); 
    		for (int i = fir[x]; ~i; i = e[i].next) {
    			int v = e[i].to; if (!ok[v]) continue; 
    			if (ds[x] + e[i].cost < ds[v]) {
    				ds[v] = ds[x] + e[i].cost;
    				if (!inq[v]) que.push(v), inq[v] = 1; 
    			} 
    		} 
    		inq[x] = 0; 
    	}
    	dis[l][r] = ds[M]; 
    }
    long long f[MAX_N]; 
    int main () { 
    #ifndef ONLINE_JUDGE 
        freopen("cpp.in", "r", stdin); 
    #endif
    	memset(fir, -1, sizeof(fir)); 
    	scanf("%d%d%d%d", &N, &M, &K, &E); 
    	for (int i = 1; i <= E; i++) {
    		int u, v, w; scanf("%d%d%d", &u, &v, &w); 
    		Add_Edge(u, v, w), Add_Edge(v, u, w); 
    	} 
    	scanf("%d", &D); 
    	for (int i = 1; i <= D; i++) {
    		int p, l, r; scanf("%d%d%d", &p, &l, &r); 
    		for (int j = l; j <= r; j++) run[p][j] = 1; 
    	} 
    	for (int i = 1; i <= N; i++)
    		for (int j = i; j <= N; j++)
    			spfa(i, j);
    	f[0] = -K; 
    	for (int i = 1; i <= N; i++) { 
    		f[i] = 1e18;
    		for (int j = 0; j < i; j++)
    			f[i] = min(f[i], f[j] + 1ll * dis[j + 1][i] * (i - j) + K); 
    	} 
    	printf("%lld
    ", f[N]); 
        return 0; 
    } 
    
  • 相关阅读:
    全国城市经纬度
    CentOS下SSH无密码登录的配置
    Nginx 1.9+PHP5.6 环境搭建
    Sphinx 2.2.11-release reference manual
    JVM 内存管理机制
    solr 3.5.0 与 tomcat 7.0.5 整合配置
    lucene 分词实现
    lucene 索引 demo
    lucene 搜索demo
    Lucene 简单API使用
  • 原文地址:https://www.cnblogs.com/heyujun/p/10552742.html
Copyright © 2011-2022 走看看