[ZJOI2006 物流运输trans] 最短路径 DP SPFA

From:http://www.lydsy.com/JudgeOnline/problem.php?id=1003

Solution:

记cost[i,j]表示i到j天不换路径的最小成本, dp[i]表示前i天的最小成本, 得dp[i] = min(dp[i], dp[j]+cost[j+1,i]+K),其中0<=j<i.

 

/**************************************************************
    Problem: 1003
    User: leezy
    Language: C++
    Result: Accepted
    Time:64 ms
    Memory:888 kb
****************************************************************/
 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define N 25
#define M 105
#define INF 0x6fffffff
#define MAX_LEVEL 32
#define NIL (-1)
#define lowbit(i) ((i)&amp;(-i))
bool inQ[N], valid[N][M];
int w[N][N], d[N], dp[M], S, T, cost[M][M];
void init(int n, int m){
    S = 1, T = n;
    for (int i = 0; i &lt;=n; ++i){
        for (int j = 0; j &lt;= n; ++j) w[i][j] = INF;
        for (int j = 0; j &lt;= m; ++j) valid[i][j] = true;
    }
}
bool check(int v, int i, int j){
    bool r = true;
    for (int k = i; k &lt;= j; ++k) r &amp;= valid[v][k];
    return r;
}
int spfa(int I, int J){
    std::queue Q;
    for (int i = S; i &lt;= T; ++i) inQ[i] = false, d[i] = INF;
    d[S] = 0; inQ[S] = true; Q.push(S);
    while ( !Q.empty() ){
        int u = Q.front(); Q.pop(); inQ[u] = false;
        for (int v = S; v &lt;= T; ++v){
            if ( w[u][v] == INF ) continue;
            if ( d[v] - d[u] &gt; w[u][v]){
                if ( check(v, I, J) ){
                    d[v] = d[u] + w[u][v];
                    if ( v != T &amp;&amp; !inQ[v] ){
                        Q.push(v); inQ[v] = true;
                    }
                }
            }
        }
    }
    return d[T];
}
int run(int n, int m, int K){
    for (int i = 1; i &lt;= m; ++i)
    for (int j = i; j &lt;= m; ++j){
        cost[i][j] = spfa(i, j);
        if ( cost[i][j] != INF )
            cost[i][j] *= (j-i+1);
    }
    dp[0] = -K;
    for (int i = 1; i &lt;= m; ++i) dp[i] = INF;
    for (int i = 1; i &lt;= m; ++i)
    for (int j = 0; j &lt; i; ++j )
    dp[i] = min(dp[i], dp[j] + cost[j+1][i] + K);
    return dp[m];
}
int main()
{
    //const char path[] = "D:\\Project\\AlgorithmExam\\test.txt";
    //freopen(path, "r+", stdin);
 
    int n,m,K,e;
    while( scanf("%d%d%d%d", &amp;n, &amp;m, &amp;K, &amp;e) != EOF ){
        init(m, n);
        for (int i = 0; i &lt; e; ++i){
            int a, b, x;
            scanf("%d%d%d", &amp;a, &amp;b, &amp;x);
            w[a][b] = w[b][a] = x;
        }
        int nn = 0;
        scanf("%d", &amp;nn);
        for (int i = 0; i &lt; nn; ++i){
            int a, b, x;
            scanf("%d%d%d", &amp;x, &amp;a, &amp;b);
            for (int i = a; i &lt;= b; ++i) valid[x][i] = false;
        }
        printf("%d\n", run(m, n, K));
    }
    return 0;
}
View Code

 

posted on 2013-12-08 21:11  leezyli  阅读(151)  评论(0编辑  收藏  举报

导航