zoukankan      html  css  js  c++  java
  • [ZJOI2006]物流运输 最短路 动态规划

    Code:

    定义状态 $dp[i]$ 为前 $i$ 天的最小代价。

    状态转移为:$dp[i]=min(dp[i],dp[j]+spfa(j+1,i)$ 这里 $spfa(i,j)$ 是指 $(i,j)$ 天中用一种最短路方案的最短路(最小花费)

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<deque>
    using namespace std;
    void setIO(string a){
        freopen((a+".in").c_str(),"r",stdin);
    }
    const int maxn=30;
    const int inf=10000000;
    int n,m;
    int tag[maxn],head[maxn], to[1000000], nex[1000000],val[1000000],edges;
    int a[maxn][200];
    long long dp[200];
    void add_edge(int u,int v,int c){
        nex[++edges]=head[u], head[u]=edges, to[edges]=v, val[edges]=c;
    }
    deque<int>Q;
    bool inq[100000];
    int d[maxn];
    int spfa(int l,int r){
        Q.clear();
        for(int i=0;i<maxn;++i) d[i]=inf;
        memset(tag,0,sizeof(tag));
        memset(inq,false,sizeof(inq));
        for(int i=1;i<=m;++i)
            for(int j=l;j<=r;++j)
                if(a[i][j]) tag[i]=1;
        Q.push_back(1);
        d[1]=0,inq[1]=true;
    
        while(!Q.empty()){
            int u=Q.front();
            Q.pop_front();
            inq[u]=false;
            for(int v=head[u];v;v=nex[v]){
                if(tag[to[v]]) continue;
                if(d[u]+val[v] < d[to[v]]){
                    d[to[v]]=d[u]+val[v];
                    if(!inq[to[v]]){
                        if(Q.empty()||d[to[v]]<=d[Q.front()]) Q.push_front(to[v]);
                        else Q.push_back(to[v]);
                        inq[to[v]]=true;
                    }
                }
            }
        }
        return d[m];
    }
    void update(long long  &a,long long b){
        if(b<a)a=b;
    }
    int main(){
        //setIO("input");
        int k,e;
        scanf("%d%d%d%d",&n,&m,&k,&e);
        for(int i=1;i<=e;++i){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add_edge(a,b,c);
            add_edge(b,a,c);
        }
    
        int cnt;
        scanf("%d",&cnt);//
        for(int i=1;i<=cnt;++i){
            int p,l,r;
            scanf("%d%d%d",&p,&l,&r);
            for(int j=l;j<=r;++j) a[p][j]=1;
        }
        for(int i=1;i<=n;++i)
        {
            dp[i]=spfa(1,i)*i;
            for(int j=1;j<i;++j) 
                update(dp[i],dp[j]+(long long)spfa(j+1,i)*(i-j)+k);
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
    

      

  • 相关阅读:
    vim发现交换文件
    Linux vim 一般模式(底线模式) 命令行模式 插入模式 记录2:
    linux的停止命令
    Linux centos7 常用命令 记录1:
    linux操作系统的关机命令
    linux解密shadow_Linux密码文件passwd和shadow分析
    mysql中root用户被忽略?
    Linux笔记01
    重装系统后恢复MySQL服务,Can't create test file C:ProgramDataMySQLMySQL
    重装JDK后,输入java -version报错:could not open " xxxxjvm.cf "
  • 原文地址:https://www.cnblogs.com/guangheli/p/9870620.html
Copyright © 2011-2022 走看看