算是一道需要动脑筋的最短路问题了,关键在于建图部分,对于n个电梯中每一个都要经过cnt个楼层,a[0],a[1],a[2],a[3],a[4],......a[cnt-1],那么对于任意两个楼层a[j],a[l],都需要建立一条a[j]到a[l]的边,以及另一条反向边。而且为了表示所属的电梯,另外用一个数组tag[e]表示边e所属的电梯,当tag[e1]!=tag[e2],应该在时间上加上60s。然后利用dijsktra+优先队列即可。
最近感觉做acm题是真真的开始入门了,不过接触到的算法,是在是少,一步一步慢慢学精吧。坚持做到每天独立的切几题,这样的成就感一定能够使得我越走越远。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #define MAXN 200 5 #define MAXM 30000 6 #define INF 1000000000 7 8 using namespace std; 9 typedef pair<int, int> pii; 10 11 int first[MAXN], T[10], a[MAXN], d[MAXN], pa[MAXN]; 12 int next[MAXM], u[MAXM], v[MAXM], w[MAXM], tag[MAXM]; 13 int i, n, k, cnt, e; 14 15 void add_edge(int from, int to, int c) 16 { 17 u[e] = from; 18 v[e] = to; 19 next[e] = first[from]; 20 w[e] = c; 21 tag[e] = i; 22 first[from] = e++; 23 } 24 void read_graph(void) 25 { 26 for(int j = 0; j < cnt; j++) 27 for(int l = j + 1; l < cnt; l++) 28 { 29 add_edge(a[j], a[l],(a[l] - a[j]) * T[i]); 30 add_edge(a[l], a[j],(a[l] - a[j]) * T[i]); 31 } 32 } 33 int cmp(int e1, int e2) 34 { 35 if(e1 == -1) 36 return 0; 37 if(tag[e1] == tag[e2]) 38 return 0; 39 return 60; 40 } 41 priority_queue<pii, vector<pii>, greater<pii> > q; 42 43 int main(void) 44 { 45 while(~scanf("%d%d", &n, &k)) 46 { 47 char ch; 48 e = 0; 49 memset(first, -1, sizeof(first)); 50 memset(pa, -1, sizeof(pa)); 51 for(i = 1; i <= n; i++) 52 scanf("%d", T + i); 53 for(i = 1; i <= n; i++) 54 { 55 cnt = 0; 56 while(1) 57 { 58 scanf("%d%c", &a[cnt], &ch); 59 cnt++; 60 if(ch == '\n') 61 { 62 read_graph(); 63 // printf("%d\n", cnt); 64 break; 65 } 66 } 67 } 68 // printf("%d\n", e); 69 for(int j = 0; j < 100; j++) 70 d[j] = INF; 71 d[0] = 0; 72 q.push(make_pair(d[0],0)); 73 while(!q.empty()) 74 { 75 pii u = q.top(); 76 q.pop(); 77 int x = u.second; 78 if(d[x] != u.first) 79 continue; 80 for(int ee = first[x]; ee != -1; ee = next[ee]) 81 if(d[v[ee]] > d[x] + w[ee] + cmp(pa[x],ee)) 82 { 83 d[v[ee]] = d[x] + w[ee] + cmp(pa[x],ee); 84 // printf("%d\n", cmp(pa[ee], ee)); 85 q.push(make_pair(d[v[ee]],v[ee])); 86 pa[v[ee]] = ee; 87 } 88 } 89 if(d[k] == INF) 90 puts("IMPOSSIBLE"); 91 else printf("%d\n",d[k]); 92 } 93 return 0; 94 }