题意:在一个虚拟的摩天大楼里,有n个电梯,有最多不超过100层的楼层,编号0~99,并且没有楼梯,每个电梯有个速度,代表移动一层需要的时间,另外电梯指在特定的楼层停留,如果要换乘电梯,则这两个电梯必须有相同的停留位置,电梯的数量和位置足够多,也就是换电梯不需要等待,但是有个换电梯的人走动时间为60s。求从0层到k层最小可能时间
思路:构图:n最多为5,楼层最多100层,那就扩展到500个,0~99代表一电梯的路线,0,101~199代表2电梯的路线,0,I*100+1~~I*100+99代表第I个电梯,电梯之间有在相同楼层停留的,则在相应顶点加上一条权为60的边,运行dijstra算法,答案在d[I*100+k]里.
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int maxn =550;
const int gap=100;
const int INF = 1<<30;
struct node
{
int d,x;
bool operator < (const node &b)const
{
return d>b.d;
}
};
struct edge
{
int from,to,w;
};
int n,k;
vector<edge> edges;
vector<int> g[maxn];
vector<int> st[5];
int sp[5],d[maxn],vis[maxn],p[maxn];
void addedge(int from,int to,int w)
{
edges.push_back(edge{from,to,w});
edges.push_back(edge{to,from,w});
int m=edges.size();
g[from].push_back(m-2);
g[to].push_back(m-1);
}
int dijstra(int s)
{
priority_queue<node,vector<node> > q;
memset(vis,0,sizeof(vis));
for(int i=0;i<maxn;i++)d[i]=INF;
d[s]=0;
q.push(node{0,s});
while(!q.empty())
{
node a=q.top();q.pop();
int x = a.x;
if(vis[x])continue;
vis[x]=1;
for(int i=0;i<g[x].size();i++)
{
edge &e=edges[g[x][i]];
if(d[e.to]>d[x]+e.w)
{
d[e.to]=d[x]+e.w;
q.push(node{d[e.to],e.to});
p[e.to]=g[x][i];
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
int v;
char c;
for(int i=0;i<=n*gap;i++)g[i].clear();
edges.clear();
for(int i=0;i<n;i++)st[i].clear();
for(int i=0;i<n;i++)scanf("%d",&sp[i]);
for(int i=0;i<n;i++)
{
while(1)
{
scanf("%d",&v);
c=getchar();
st[i].push_back(v);
if(c!=' ')break;
}
}
for(int i=0;i<n;i++)
{
for(int j=1;j<st[i].size();j++)
if(st[i][j-1]==0)
addedge(st[i][j-1],st[i][j]+i*gap,sp[i]*(st[i][j]-st[i][j-1]));
else
addedge(st[i][j-1]+i*gap,st[i][j]+i*gap,sp[i]*(st[i][j]-st[i][j-1]));
}
for(int i=0;i<n;i++)
for(int j=0;j<st[i].size();j++)
{
for(int k=i+1;k<n;k++)
for(int l=0;l<st[k].size();l++)
{
if(st[i][j]==st[k][l])
{
addedge(st[i][j]+i*gap,st[k][l]+k*gap,60);
}
}
}
dijstra(0);
int ans=1<<29;
for(int i=0;i<n;i++)
{
if(ans>d[k+i*gap])
ans=d[k+i*gap];
}
if(ans==1<<29)
printf("IMPOSSIBLE\n");
else
printf("%d\n",ans);
}
}