[BZOJ1003][ZJOI2006]物流运输trans

被简单错误卡

#include<iostream>
#include<vector>
#include<set>
using namespace std;
const int INF=999999999;
int n, m, K, dp[102], disabled[102];
vector<pair<int,int> > edge[22];
int main() {
int e; cin>>n>>m>>K>>e;
    while(e--) {
        int x,y,z; cin>>x>>y>>z;
        edge[x].push_back(make_pair(y,z));
        edge[y].push_back(make_pair(x,z));
    }
    int d; cin>>d;
    while(d--) {
        int x,y,z; cin>>x>>y>>z;
        if (y>z) y+=z,z=y-z,y-=z;
        for(;y<=z;y++) disabled[y]|=(1<<x);
    }
    // for(int i=0;i<=n;i++) cout<<disabled[i]<<" "; cout<<endl;
    for(int i=1;i<=n;i++){
        // cout<<"day "<<i<<":"<<endl;
        dp[i]=INF;
        for (int j=0;j<i;j++) if(dp[j]<INF){
            int s=0;
            for(int k=j+1;k<=i;k++) s|=disabled[k];
            vector<int> dist; dist.push_back(0);
            for (int k=1;k<=m;k++) dist.push_back(INF);
            multiset<pair<int,int> > q;
            q.insert(make_pair(0,1));
            while(!q.empty()){
                int u=q.begin()->first;
                int v=q.begin()->second;
                if (u<=dist[v]){ // 队列中可能有非最佳的,舍弃
                    dist[v]=u;
                    if(v==m) break; // 找到到终点的最短路了... 
                    for(int k=0;k<edge[v].size();k++){
                        int x=edge[v][k].first, y=u+edge[v][k].second; // x:编号,y:距离
                        if(0==(1&(s>>x))&&y<dist[x]){
                            dist[x]=y;
                            q.insert(make_pair(y,x));
                        }
                    }
                }
                q.erase(q.begin());
            }
            if (dist[m]<INF) dp[i]=min(dp[i],dp[j]+dist[m]*(i-j)+K);
            // cout<<"j="<<j<<",mask="<<s<<",dist[m]="<<dist[m]<<",dp["<<i<<"]="<<dp[i]<<endl;
            q.clear();
            dist.clear();
        }
        // cout<<endl;
    }
    cout<<dp[n]-K<<endl;
    return 0;
}

 

posted @ 2016-01-04 14:08  海豚爸爸  阅读(160)  评论(0编辑  收藏  举报