您的位置:首页 > 运维架构

习题11-7 UVa 10801 Lift Hopping SPFA最短路

2017-08-09 20:40 513 查看
题意分析:

从0层开始,一共有n台电梯供你到达目的地k层。每台电梯往上走一层都要消耗t[i]的时间,并且电梯只能在特定的楼层停下,换乘电梯要花费60s的时间,而且呢,你不能用楼梯上楼,只能搭电梯。。。。(hentai!)问:最快到达楼层k的时间是多少?不能到达就输出IMPOSSIBLE。

解题思路:

这题技巧就是体现在建图上,用邻接矩阵更好,图建好了,用dijkstra或spfa跑一遍就行了。

具体建图就是用G[i][j]代表从楼层i到楼层j的最小距离。这里不考虑换乘,先这样把图建好。

对于换乘,我们在dijkstra更新节点的时候使用。具体为:dist[y] = min(dist[y], d[x] + G[x][y] + 60);

这里更新时加上60s的具体理由在于:这里我们默认第一次进电梯算是换乘,所以加上60s。这样不管是一路搭到底(每个dist[i]都加60,一起比较起来没有影响),还是有换乘(本来就该加60s嘛)。都不会影响。

这样在计算最终结果时,减去60就是最终的结果了(因为默认了第一次进入电梯算换乘)。

#include<bits/stdc++.h>
const int maxn=105;
const int INF=0x3f3f3f3f;
typedef long long LL;
using namespace std;
int G[maxn][maxn];
int dist[maxn];
int vis[maxn];
int sp[maxn];
int N,K;
int a[maxn];
struct Edge
{
int e,w;
Edge(){}
Edge(int _e,int _w):e(_e),w(_w){}
bool operator <(const Edge &v)const{
return w>v.w;
}
};
void graph(int k,int count)
{
for(int i=0;i<count;i++)
{
for(int j=i+1;j<count;j++)
{
int s=a[i];
int e=a[j];
int w=(e-s)*sp[k];
if(G[s][e]>w) G[s][e]=G[e][s]=w;
}
}
}
void input()
{
for(int i=0;i<N;i++) cin>>sp[i];
string line;
getchar();
for(int i=0;i<N;i++)
{
int x,count=0;
/*
char c;
do{
cin>>a[count++];
}while(getchar()!='\n');
*/
getline(cin,line);
stringstream ss(line);
while(ss>>x)
{
a[count++]=x;
}
graph(i,count);
}
}

void spfa(int S)
{
memset(vis,0,sizeof(vis));
memset(dist,INF,sizeof(dist));
queue<int>q;
dist[S]=0;
vis[S]=1;
q.push(S);
while(!q.empty())
{
int s=q.front();q.pop();
vis[s]=0;
for(int i=0;i<=99;i++)
{
if(dist[i]>dist[s]+G[s][i]+60)
{
dist[i]=dist[s]+G[s][i]+60;
if(!vis[i])
{
vis[i]=1;
q.push(i);
}
}
}
}
if(dist[K]==INF) puts("IMPOSSIBLE");
else cout<<max(0,dist[K]-60)<<endl; //小心目标楼层为0的情况
}

void dij(int S)
{
memset(vis,0,sizeof(vis));
memset(dist,INF,sizeof(dist));
priority_queue<Edge> q;
q.push(Edge(S,0));
dist[S]=0;
while(!q.empty())
{
int s=q.top().e;q.pop();
if(vis[s]) continue;
vis[s]=1;
for(int i=0;i<=99;i++)
{
if(!vis[i]&&dist[i]>dist[s]+G[s][i]+60)
{
dist[i]=dist[s]+G[s][i]+60;
q.push(Edge(i,dist[i]));
}
}
}
if(dist[K]==INF) puts("IMPOSSIBLE");
else cout<<max(0,dist[K]-60)<<endl;
}

int main()
{
// freopen("E:\\ACM\\test.txt","r",stdin);
while(cin>>N>>K)
{
memset(G,INF,sizeof(G));

input();
// spfa(0);
dij(0);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva 10801 最短路 ACM