1003: [ZJOI2006]物流运输trans

spfa+dp;

刚刚开始一直想不通怎么判断他是否换了道;

后来才知道,将那个时间段打包,找出这段时间内的最短路;

真是太奇妙了!

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 1e6
using namespace std;

int map[22][22];
int pass[22][105];
int d[22],inq[22];
int n,m,k,e;
int dp[22];
int spfa(int s,int t)
{
    queue<int>q;
    for(int i=1; i<=m; i++)
    {
        d[i]=inf;
        inq[i]=0;
    }
    d[1]=0;
    q.push(1);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        inq[u]=0;
        for(int i=1; i<=m; i++)
        {
            if(map[u][i]&&(pass[i][t]==pass[i][s])&&(d[i]>d[u]+map[u][i]))
            {
                d[i]=d[u]+map[u][i];
                if(!inq[i])
                {
                    inq[i]=1;
                    q.push(i);
                }
            }
        }
    }
    return d[m];
}

int main()
{
    int a,b,c,p;
    scanf("%d%d%d%d",&n,&m,&k,&e);
    while(e--)
    {
        scanf("%d%d%d",&a,&b,&c);
        if(map[a][b]==0||map[a][b]>c)
            map[a][b]=map[b][a]=c;
    }
    scanf("%d",&p);
    while(p--)
    {
        scanf("%d%d%d",&a,&b,&c);
        for(int i=b; i<=c; i++)
            pass[a][i]=1;
    }
    for(int i=1; i<=m; i++)
        for(int j=1; j<=n; j++)
            pass[i][j]=pass[i][j-1]+pass[i][j];
    for(int i=1; i<=n; i++)
    {
        dp[i]=inf;
        for(int j=0; j<i; j++)
            dp[i]=min(dp[i],dp[j]+spfa(j,i)*(i-j)+k);
    }
    printf("%d
",dp[n]-k);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/yours1103/p/3456752.html