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

来源:互联网 发布:python 聚类算法 编辑:程序博客网 时间:2024/06/01 19:37

题意分析:

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


原创粉丝点击