[BZOJ1003][ZJOI2006]物流運輸trans

最短路+dp

a[i][j]表示符合第i天到第j天情況的一條最短路

dp方程 dp[i]=min(dp[i],dp[j]+k+(i-j)*a[j+1][i]);

注意要開long long...

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
const int oo=99999999;
struct node
{
    int t,x;
};
vector<node> mp[21];
int n,m,k,e,a[110][110];
bool f[110][110];
int djs(int s,int t)
{
    bool vis[110],flag[110];
    int dist[110];
    for (int i=1;i<=m;i++)
    dist[i]=oo;
    dist[1]=0;
    memset(vis,true,sizeof(vis));
    memset(flag,true,sizeof(flag));
    for (int i=1;i<=m;i++)
    for (int j=s;j<=t;j++)
    if (!f[j][i]) flag[i]=false;
    for (int i=1;i<=m-1;i++)
    {
        int min=oo,u;
        for (int j=1;j<=m;j++)
        if (flag[j]&&vis[j]&&dist[j]<min) u=j,min=dist[j];
        vis[u]=false;
        for (int j=0;j<(int)mp[u].size();j++)
        if (flag[mp[u][j].t])
        {
            if (dist[u]+mp[u][j].x<dist[mp[u][j].t])
            dist[mp[u][j].t]=dist[u]+mp[u][j].x;
        }
    }
    return dist[m];
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&k,&e);
    for (int i=1;i<=e;i++)
    {
        int s,t,x;
        scanf("%d%d%d",&s,&t,&x);
        node tt;
        tt.t=t;
        tt.x=x;
        mp[s].push_back(tt);
        tt.t=s;
        tt.x=x;
        mp[t].push_back(tt);
    }
    memset(f,true,sizeof(f));
    int d;
    scanf("%d",&d);
    for (int i=1;i<=d;i++)
    {
        int ta,tb,tc;
        scanf("%d%d%d",&ta,&tb,&tc);
        for (int j=tb;j<=tc;j++)
        f[j][ta]=false;
    }
    for (int i=1;i<=n;i++)
    for (int j=i;j<=n;j++)
    a[i][j]=djs(i,j);
    long long dp[110];
    dp[1]=a[1][1];
    for (int i=2;i<=n;i++)
    {
        dp[i]=a[1][i]*(long long)i;
        for (int j=1;j<i;j++)
        dp[i]=min(dp[i],dp[j]+k+(i-j)*(long long)a[j+1][i]);
    }
    cout<<dp[n]<<endl;
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章