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

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1003

题解:

dp就好,令dp[i]表示第i天的答案,那么dp[i]=min{Cost(1,i),Cost(j+1,i)+dp[j]+K},其中Cost(i,j)表示从i到j都用同一种方案。这种dp和划分问题很类似。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<climits>
#define INF 0x3f3f3f3f
#define MAX_M 220
#define MAX_N 1110
using namespace std;

int N,M,K,E;

int dp[MAX_N];
int d[MAX_M];

queue<int> que;
bool inQue[MAX_M];

struct edge {
public:
    int to, cost;

    edge(int t, int c) : to(t), cost(c) { }

    edge() { }
};

vector<edge> G[MAX_M];
bool used[MAX_M];

vector<int> days[MAX_N];

int spfa() {
    while (que.size())que.pop();
    memset(inQue, 0, sizeof(inQue));
    fill(d, d + M + 1, INF);
    que.push(1);
    inQue[1] = 1;
    d[1] = 0;
    while (que.size()) {
        int u = que.front();
        que.pop();
        inQue[u]=0;
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].to, c = G[u][i].cost;
            if (d[v] > d[u] + c && (!used[v])) {
                d[v] = d[u] + c;
                if (!inQue[v]) {
                    inQue[v] = 1;
                    que.push(v);
                }
            }
        }
    }
    return d[M];
}

int COST(int i,int j) {
    memset(used, 0, sizeof(used));
    for (int k = i; k <= j; k++)
        for (int t = 0; t < days[k].size(); t++)
            used[days[k][t]] = 1;
    int tmp=spfa();
    if(tmp==INF)return INF;
    return (j - i + 1) * tmp;
}

int main() {
    //freopen("1003.in", "r", stdin);
    //freopen("1003.out", "w", stdout);
    scanf("%d%d%d%d", &N, &M, &K, &E);
    for (int i = 0; i < E; i++) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        G[u].push_back(edge(v, c));
        G[v].push_back(edge(u, c));
    }
    int D;
    scanf("%d",&D);
    while (D--) {
        int P, a, b;
        scanf("%d%d%d", &P, &a, &b);
        for (int i = a; i <= b; i++)days[i].push_back(P);
    }
    for (int i = 1; i <= N; i++) {
        dp[i] = COST(1,i);
        for (int j = 1; j < i; j++)
            dp[i] = min(dp[i], COST(j + 1, i) + dp[j] + K);
    }
    printf("%d\n", dp[N]);
    return 0;
}
时间: 2024-10-22 08:12:17

BZOJ 1003: [ZJOI2006]物流运输trans SPFA+DP的相关文章

BZOJ 1003: [ZJOI2006]物流运输(spfa+dp)

http://www.lydsy.com/JudgeOnline/problem.php?id=1003 题意: 思路: 首先用spfa计算一下任意两天之内的最短路,dis[a][b]表示的就是在第a天~第b天从1到m的最短路. 接下来就是dp了,f[i]表示前i天的最小代价,那么状态转移方程就是: f[i]=min(f[i],f[j]+dis[j+1][i]*(i-j)+k) 注意:边界条件f[0]=-k! 1 #include<iostream> 2 #include<algorit

BZOJ 1003: [ZJOI2006]物流运输trans

二次联通门 : BZOJ 1003: [ZJOI2006]物流运输trans /* BZOJ 1003: [ZJOI2006]物流运输trans Spfa + Dp Spfa预处理出i到j天的最小花费 然后N^2 dp即可 */ #include <cstdio> #include <iostream> #include <cstring> #include <queue> #define INF 1e6 const int BUF = 12312313;

bzoj 1003: [ZJOI2006]物流运输trans 最短路+dp

题目链接 1003: [ZJOI2006]物流运输trans Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5246  Solved: 2157[Submit][Status][Discuss] Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无

BZOJ 1003: [ZJOI2006]物流运输trans DP+最短路

Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输路线,让货物能够按时到达目的地.但是修改路线是一件十分麻烦的事情,会带来额外的成本.因此物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小. Input 第一行是四个整数n(1<=n<=100).m(1&

BZOJ 1003 ZJOI2006 物流运输trans 动态规划+SPFA

题目大意:给定一个无向图,运输n天,其中有些天有些点不能走,更换路线代价为k,求代价总和 首先令cost[i][j]为第i天到第j天都走同一路线的最小花销 这个用SPFA处理 然后就是动规的问题了 令f[i]为1~i天的最小花销 则f[i]=min{ f[j]+cost[j+1][i]+k } ( 0<=j<i ) 注意m和n别写反 乘天数之前要特判是不是正无穷 #include<cstdio> #include<cstring> #include<iostrea

bzoj 1003 [ZJOI2006]物流运输(最短路+dp)

[ZJOI2006]物流运输 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8973  Solved: 3839[Submit][Status][Discuss] Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输

BZOJ.1003.[ZJOI2006]物流运输(DP 最短路Dijkstra)

题目链接 容易看出是个最短路+DP.既然答案和天数有关,那么就令f[i]表示前i天最小成本. 这个转移很好想: f[i]=min(f[i],f[j]+cost(j+1,i)+K),cost(j+1,i)即第j+1天到第i天(使用同一道路)所需花费,即最短路,这个可以预处理出来. 注意是否可行的判断. //880kb 88ms //好像很吉利啊 #include <queue> #include <cstdio> #include <cctype> #include &l

[bzoj]1003: [ZJOI2006]物流运输

Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输路线,让货物能够按时到达目的地.但是修改路线是一件十分麻烦的事情,会带来额外的成本.因此物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小. Input 第一行是四个整数n(1<=n<=100).m(1&

1003: [ZJOI2006]物流运输 最短路+dp

https://www.lydsy.com/JudgeOnline/problem.php?id=1003 数据范围很小,怎么瞎搞都行,n方dp,然后跑出最短路暴力转移,需要注意的是不能使用的可能有多个区间 /************************************************************** Problem: 1003 User: walfy Language: C++ Result: Accepted Time:180 ms Memory:1400 k