您的位置:首页 > 其它

【BZOJ1003】【ZJOI2006】物流运输trans 最短路预处理+动态规划

2015-03-23 20:46 363 查看

链接:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/44569117");
}


题解:

首先我们跑出fi,jf_{i,j}表示i到j这些天都是相同路线的最小代价。

然后暴力维护gig_i表示前i天最小代价。

fi,jf_{i,j}可以枚举i,ji,j,暴力处理哪些点不能用,然后跑最短路。

时间复杂度

暴力处理废点O(n3m)O(n^3m)

SPFA 是O(n2spfa)O(n^2 spfa)大约O(n2m2)?O(n^2m^2)?

反正能过。

然后暴力处理废点部分可以缩掉一个nn降低时间复杂度上限。

就是类似利用单调性质哒。每次枚举ii后都单调处理。详见代码。

代码:

p、n、m、y:天数、点数、边数、改路代价。

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 110
#define M 1300
#define inf 0x3f3f3f3f
using namespace std;
struct Eli
{
    int v,len,next;
}e[M];
int head
,cnt;
inline void add(int u,int v,int len)
{
    e[++cnt].v=v;
    e[cnt].len=len;
    e[cnt].next=head[u];
    head[u]=cnt;
}

bool Dida
,in
;
int dist
;
queue<int>q;
inline void spfa()
{
    memset(dist,0x3f,sizeof dist);
    int i,u,v;
    q.push(1),dist[1]=0;
    while(!q.empty())
    {
        u=q.front(),in[u]=0,q.pop();
        for(i=head[u];i;i=e[i].next)
        {
            v=e[i].v;
            if(Dida[v])continue;
            if(dist[v]>dist[u]+e[i].len)
            {
                dist[v]=dist[u]+e[i].len;
                if(!in[v])q.push(v),in[v]=1;
            }
        }
    }
    return ;
}

int n,m,p,y;
bool dida

;

int f

,g
;

int main()
{
    freopen("test.in","r",stdin);

    int i,j,k;
    int a,b,c;

    scanf("%d%d%d%d",&p,&n,&y,&m);
    while(m--)
    {
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c),add(b,a,c);
    }
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d%d%d",&a,&b,&c);
        for(i=b;i<=c;i++)dida[a][i]=1;
    }
    for(i=1;i<=p;i++)
    {
        memset(Dida,0,sizeof Dida);
        for(j=i;j<=p;j++)
        {
            for(k=1;k<=n;k++)
                Dida[k]|=dida[k][j];
            spfa();
            f[i][j]=dist
;
        }
    }
    for(i=1;i<=p;i++)g[i]=(f[1][i]<inf)?(f[1][i]*i):inf;
    for(i=1;i<=p;i++)for(j=0;j<i;j++)if(f[j+1][i]<inf)
        g[i]=min(g[i],g[j]+f[j+1][i]*(i-j)+y);
    printf("%d\n",g[p]);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: