题意:
有n<6部电梯,给出每部电梯可以停的一些特定的楼层,要求从0层到达第k层出来,每次换乘需要60秒,每部电梯经过每层所耗时不同,具体按 层数*电梯速度 来算。问经过多少秒到达k层(k可以为0)?
思路:
dijkstra再加一些特殊的处理就行了。首先要考虑,如何建图:
(1)每层作为一个点。但是特定路径可以有多种权,比如从2->5可以坐1号电梯10s,但是坐2号只需要5s,所以有重边。
(2)k=0时,不耗时间。
(3)有多种路径可达同一楼层且权值相同,那么从本楼层到另一楼层有多种选择,有时可以不换电梯,有时需要换。比如到达5楼的有2条路径,权都是5,但是是两部不同的电梯1和2,此时有其他电梯可以从5到7楼,其中有一部仍是电梯1,如果坐电梯1则不需要换乘时间,坐其他电梯就要了。所以要记录到某个点权值相等的电梯号。
1 #include <bits/stdc++.h>
2 #define LL long long
3 #define pii pair<int,int>
4 #define INF 0x7f7f7f7f
5 using namespace std;
6 const int N=1010;
7 int take[6];
8 char s[1000];
9 vector<int> lift[6], vect[500];
10 int cost[N], vis[N];
11 struct node
12 {
13 int from, to, lift, cost;
14 node(){};
15 node(int from,int to,int lift,int cost):from(from),to(to),lift(lift),cost(cost){};
16 }edge[100000];
17 int edge_cnt;
18
19 void add_node(int from,int to,int lift,int cost)
20 {
21 edge[edge_cnt]=node(from,to,lift,cost);
22 vect[from].push_back(edge_cnt++);
23 }
24
25 void build_graph(int n) //重新建图
26 {
27 for(int i=0; i<n; i++)
28 {
29 for(int j=0; j<lift[i].size(); j++)
30 {
31 for(int t=j+1; t<lift[i].size(); t++)
32 {
33 int a=lift[i][j];
34 int b=lift[i][t];
35 add_node(a,b,i,(b-a)*take[i]);
36 add_node(b,a,i,(b-a)*take[i]);
37 }
38 }
39 }
40 }
41
42 int dijkstra(int s,int e)
43 {
44 vector<int> flo[101];
45 memset(cost,0x7f,sizeof(cost));
46 memset(vis,0,sizeof(vis) );
47
48 priority_queue<pii,vector<pii>,greater<pii> > que;
49 que.push( make_pair(0,s));
50 cost[s]=0;
51 while(!que.empty())
52 {
53 int x=que.top().second;que.pop();
54 if(vis[x]) continue;
55
56 vis[x]=1;
57 for(int i=0; i<vect[x].size(); i++)
58 {
59 node e=edge[vect[x][i]];
60 int ext=60;
61
62 for(int j=0; j<flo[e.from].size(); j++) //如果有一个匹配,就不用额外时间
63 if( flo[e.from][j]==e.lift ) ext=0;
64
65 if(cost[e.to]>=cost[e.from]+ext+e.cost )
66 {
67 if( cost[e.to]>cost[e.from]+ext+e.cost ) flo[e.to].clear();
68 flo[e.to].push_back(e.lift);
69
70 cost[e.to]= cost[e.from] +ext +e.cost;
71 que.push( make_pair(cost[e.to], e.to) );
72 }
73 }
74 }
75 return cost[e];
76 }
77
78 int main()
79 {
80 freopen("input.txt", "r", stdin);
81 int n, k;
82 while(~scanf("%d%d",&n,&k))
83 {
84 for(int i=0; i<n; i++) lift[i].clear();
85 for(int i=0; i<101; i++) vect[i].clear();
86 memset(s,0,sizeof(s));
87
88 for(int i=0; i<n; i++) scanf("%d",&take[i]);
89 getchar();
90 for(int i=0; i<n; i++)
91 {
92 lift[i].clear();
93 gets(s);
94 int p=0;
95 while(s[p]!='\0')
96 {
97 if(s[p]==' ') p++;
98 int tmp=0;
99 while(s[p]!=' ' &&s[p]!='\0' ) tmp=tmp*10+(s[p++]-'0');
100 lift[i].push_back(tmp);
101 }
102 }
103 build_graph(n);
104 int ans=dijkstra(0,k);
105 if(!k) puts("0");
106 else if(ans==INF) puts("IMPOSSIBLE");
107 else printf("%d\n", ans-60 ) ;
108 }
109 return 0;
110 }
AC代码