Luogu P1772 [ZJOI2006]物流运输

SPFA预处理road
f[i]表示前i天的最小成本
emmmm……dp方程是看题解的
一看dp就怂

#include<cstdio>
#include<cstring>

int len=0,can[1100];
struct nod1{int x,y,c,next;}a[1100];
struct nod2{int v=0,s=999999999;}b[1100];
long long road[1010][1010],f[1000100];
int n,m,e,k,d,first[1010],t[1010][1010];
//空间不要开太大!第一次RE就是因为这个。。。 

long long minn(long long x,long long y)
{
    //一直跑不出样例就是因为这里的long long 都打成了int。。。又是一个教训 
    return x<y?x:y;
}

int ins(int x,int y,int c)
{
    len++;
    a[len].x=x;
    a[len].y=y;
    a[len].c=c;
    a[len].next=first[x];
    first[x]=len;
}

int spfa(int l,int r)
{
    memset(can,0,sizeof(can));
    for(int i=1;i<=n;i++)
    {//这里!!!让我WA了好几次90
     //就是因为for i-m for 成了1-n
     //=-=。。。 
        b[i].s=999999999;
        b[i].v=0;
    }
    int tou=1,wei=2;
    f[1]=1;
    b[1].s=0;
    b[1].v=1;
    for(int i=l;i<=r;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(t[i][j])can[j]=1;
        }//通不通 
    }
    while(tou<wei)
    {
        int x=f[tou];
        for(int i=first[x];i;i=a[i].next)
        {
            int y=a[i].y;
            if((can[y]!=1)&&b[y].s>b[x].s+a[i].c)
            {
                b[y].s=b[x].s+a[i].c;
                if(b[y].v==0)
                {
                    b[y].v=1;
                    f[wei]=y;
                    wei++;
                }
            }
        }
        tou++;
        b[x].v=0;
    }
    return b[m].s;
}

void work()
{
    for(int i=1;i<=n;i++)
    {
       f[i]=(long long)road[1][i]*i;
       for(int j=1;j<i;j++)
       {//这里有点神奇
        //好像for 0~i-1 和1~i-1 都可以。。。好像2开始也可以。。。 
            f[i]=minn(f[i],f[j]+road[j+1][i]*(i-j)+k);
       }  
        //printf("%d",f[i]);
    }

}

int main()
{
    scanf("%d %d %d %d",&n,&m,&k,&e);
    for(int i=1;i<=e;i++)
    {
        int x,y,z;
        scanf("%d %d %d",&x,&y,&z);
        ins(x,y,z);ins(y,x,z);
    }
    scanf("%d",&d);
    for(int i=1;i<=d;i++)
    {
        int x,l,r;
        scanf("%d %d %d",&x,&l,&r);
        for(int j=l;j<=r;j++)
        {
            t[j][x]=1;
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            road[i][j]=spfa(i,j);
            //printf("%d\n",road[i][j]);
        }
    }
    work();
    printf("%d",f[n]);
}

猜你喜欢

转载自blog.csdn.net/qq_42142540/article/details/80216103