题意:电梯调度的加强版,有N个电梯,每个电梯只能到规定的楼层停,从A电梯到B电梯时需要花5秒时间,并且还需要等待B电梯停到这层花费的时间(按最糟糕的情况处理)
分析:因为最优策略是每个电梯最多搭乘一次,若搭乘多次则花费的时间会更多..所以不用考虑每个电梯搭乘后的状态..
松弛时一定是一个电梯到另一个电梯,因为在同一个电梯无法松弛!
// File Name: 10841.cpp // Author: Zlbing // Created Time: 2013/5/19 12:58:02 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define LL long long #define REP(i,r,n) for(int i=r;i<=n;i++) #define RREP(i,n,r) for(int i=n;i>=r;i--) const int MAXN=150; int n,k; int T[MAXN]; int G[MAXN][MAXN]; int f[MAXN]; int maxn[MAXN]; int minn[MAXN]; struct node{ int u,cost; bool operator <(const node& rhs)const{ return cost>rhs.cost; } }; int vis[MAXN]; int d[MAXN]; int dij() { CL(vis,0); CL(d,-1); priority_queue<node> Q; Q.push((node){0,0}); node t,tt; while(!Q.empty()) { t=Q.top(); Q.pop(); if(t.u==k)return t.cost; int u=t.u; int cost=t.cost; if(vis[u])continue; vis[u]=1; for(int i=0;i<n;i++) if(G[i][u]){ int a=T[i]*(maxn[i]-u); int b=T[i]*(u-minn[i]); int tmp=max(a,b); for(int j=0;j<105;j++) { if(u==j)continue; if(G[i][j]) { if(u==0) { tt.u=j; tt.cost=tmp+cost+abs(j-u)*T[i]; Q.push(tt); //printf("i=%d %d->%d cost=%d\n",i,u,tt.u,tt.cost); } else{ tt.u=j; tt.cost=tmp+cost+abs(j-u)*T[i]+5; Q.push(tt); //printf("i=%d %d->%d cost=%d\n",i,u,tt.u,tt.cost); } } } } } return -1; } int main() { while(~scanf("%d%d",&n,&k)) { REP(i,0,n-1) { scanf("%d",&T[i]); } CL(G,0); CL(f,0); char ch[MAXN*10]; CL(minn,-1); CL(maxn,-1); REP(i,0,n-1) { int a=0; do{ scanf("%d",&a); G[i][a]=1; if(maxn[i]==-1) maxn[i]=a; else maxn[i]=max(maxn[i],a); if(minn[i]==-1) minn[i]=a; else minn[i]=min(minn[i],a); }while(getchar()!='\n'); } int ans=dij(); if(ans==-1) printf("IMPOSSIBLE\n"); else printf("%d\n",ans); } return 0; }