[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; }