[OJ]1014:西湖三人行
Description
去年10月份,FightOn队伍的三个人YZW、HKX、WX在参加完杭州赛区后想到杭州最有名的西湖去玩。他们所能选择的交通方式只有三种:
-
走路,速度为
1m/s
,每人每千米花费1
元钱(因为他们会消耗体力,需要买水、食物等)。 -
搭公交,速度为
4m/s
,每人2
元,每条公交路线都按照一定的方向。 -
打的,速度为
8m/s
,起步价3
千米内10
元,以后每千米2
元,每个站点都有的士。
当然杭州的交通秩序不像长沙,所以如果想改变交通方式只能在每个站点改换。三个人现在囊中羞涩,但又比较急,所以他们想在不超过L(0<L<101)
元钱的前提下尽快到达西湖。
此处假设三人在站点改换交通方式时不考虑等待时间,并且公交和的士始终匀速。
Input
第一行一个数字T
表示接下来有T
组数据(T<11)
。
每组数据的第一行有6
个整数L
,N
,M
,S
,T
,B
。表示图共有N
个站点(N<100)
,M
表示共有M
条路(M<1000)
,起点为S
,西湖的位置为T(S≠T)
,共有B
条公交线路(B<200)
。
接下来M
行,每行3
个整数u
,v
,w
,表示站点u
与v
之间存在一条路距离为w
千米(0<w<10)
,u
与v
可以互达. 此处假设任意两点之间最多有一条直接相连的路。
接下来B
行,每行第一个为K(1<K<20)
,表示当前公交车共经过K
个站点,接下来K
个整数,表示当前公交车依次经过K
个站点的编号(此K
个站点保证两两互达,此路线并不代表公交车可以原路返回)。
Output
如果能够花费不超过L
元达到西湖,则输出达到西湖所需的最少秒数,否则输出“no
”(不带引号)。
#include <stdio.h> #define MAX_VERTICES 100 #define MAX_EDGES 1000 #define MAX_BUSES 200 #define MAX_DURATION 1000000 #define TAXI_KM_TIME 125 #define BUS_KM_TIME 250 #define WALK_KM_TIME 1000 typedef struct _Graph{ int vertex_num; int edge_num; int vertices[MAX_VERTICES]; int edges[MAX_VERTICES][MAX_VERTICES]; int visited[MAX_VERTICES]; }Graph; typedef struct _Bus{ int bus_num; int lines[MAX_BUSES][MAX_VERTICES]; }Bus; typedef struct _Route{ int vertex; int method; }Route; Route route[655350]; int top = -1; void graph_init(Graph *G){ int i,j; G->vertex_num = 0; G->edge_num = 0; for(i = 0; i < MAX_VERTICES; i++){ G->vertices[i] = -1; G->visited[i] = 0; for(j = 0; j < MAX_VERTICES; j++){ G->edges[i][j] = -1; } } } int graph_first_vertex(Graph *G, int root){ int i; for(i=1; i<MAX_VERTICES; i++){ if(G->edges[root][i] > 0){ return i; } } return -1; } int graph_next_vertex(Graph *G, int root, int from){ int i; for(i=from+1; i<MAX_VERTICES; i++){ if(G->edges[root][i] > 0){ return i; } } return -1; } /* money means the money remained, method means traffic method, -1 stands for taxi, -2 stands for walk, others stands for bus */ int graph_bfs(Graph *G, int from, int dst, int money, int last_method, int last_dist, Bus *B, int duration){ int first,next,tmp,min,cost,i,j; int _duration,_money,_method,_next; int duration_taxi, duration_bus, duration_walk; int a_top, b_top, walk_top, k, m; int mm,nn; if(from == dst){ return duration; } if(money<0){ return -1; } /* Find first */ a_top = b_top = -1; next = graph_first_vertex(G, from); min = MAX_DURATION; while(next>=0){ if(G->visited[next] != 1){ G->visited[next] = 1; cost = G->edges[from][next]; //Taxi _duration = duration + TAXI_KM_TIME * cost; if(last_method == -2){ tmp = 3 - last_dist; if(tmp > 0){ _money = money - (cost - tmp) * 2; }else{ _money = money - cost * 2; } last_dist += cost; }else{ _money = money - 10; tmp = cost - 3; if(tmp > 0){ _money -= tmp * 2; } last_dist = cost; } if(_money >= 0){ b_top = top; _duration = graph_bfs(G, next, dst, _money, -2, last_dist, B, _duration); if(_duration > 0 && _duration < min){ min = _duration; _method = -2; _next = next; if(a_top >= 0){ m = a_top; for(k=b_top+1; k<=top; k++){ route[++m].vertex = route[k].vertex; route[m].method = route[k].method; } top = m; }else{ a_top = b_top; } }else{ top = b_top; b_top = -1; } } //Bus for(i=0; i<B->bus_num; i++){ j=1; while(j < MAX_VERTICES && B->lines[i][j]>=0 && (B->lines[i][j-1] != from || B->lines[i][j] != next) ){ j++; } if(j == MAX_VERTICES || B->lines[i][j] < 0){ continue; } _duration = duration + BUS_KM_TIME * cost; _money = money; if(last_method != i){ _money -= 2*3; } if(_money >= 0){ b_top = top; _duration = graph_bfs(G, next, dst, _money, i, 0, B, _duration); if(_duration > 0 && _duration < min){ min = _duration; _method = i; _next = next; if(a_top >= 0){ m = a_top; for(k=b_top+1; k<=top; k++){ route[++m].vertex = route[k].vertex; route[m].method = route[k].method; } top = m; }else{ a_top = b_top; } }else{ top = b_top; b_top = -1; } } } //Walk _duration = duration + WALK_KM_TIME * cost; _money = money - 1*3*cost; if(_money >= 0){ b_top = top; _duration = graph_bfs(G, next, dst, _money, -1, 0, B, _duration); if(_duration > 0 && _duration < min){ min = _duration; _method = -1; _next = next; if(a_top >= 0){ m = a_top; for(k=b_top+1; k<=top; k++){ route[++m].vertex = route[k].vertex; route[m].method = route[k].method; } top = m; }else{ a_top = b_top; } }else{ top = b_top; b_top = -1; } } G->visited[next] = -1; }else{ } next = graph_next_vertex(G, from, next); } G->visited[from] = 1; if(min == MAX_DURATION){ return -1; } // printf(" %d->%d (%d)\n", from, _next, _method); route[++top].vertex = _next; route[top].method = _method; return min; } void bus_init(Bus *B){ int i,j; B->bus_num = 0; for(i=0; i<MAX_BUSES; i++){ for(j=0; j<MAX_VERTICES; j++){ B->lines[i][j] = -1; } } } void main(){ int tests, l, n, m, s, t, b; int u,v,w; int duration; Graph G; Bus B; scanf(" %d", &tests); while(tests--){ scanf(" %d %d %d %d %d %d", &l, &n, &m, &s, &t, &b); graph_init(&G); G.vertex_num = n; G.edge_num = m; while(m--){ scanf(" %d %d %d", &u, &v, &w); G.edges[u][v] = w; G.edges[v][u] = w; } bus_init(&B); B.bus_num = b; for(n=0; n<b; n++){ scanf(" %d", &u); m = 0; for(m=0; m<u; m++){ scanf(" %d", &v); B.lines[n][m] = v; } } G.visited[s] = 1; duration = graph_bfs(&G, s, t, l, -2, 0, &B, 0); if(duration<0){ printf("no\n"); }else{ printf("%d\n", duration); } while(top>=0){ // printf(" %d---(%d)\n", route[top].vertex, route[top].method); top--; } } }
标签: C
日历
最新微语
- 有的时候,会站在分叉路口,不知道向左还是右
2023-12-26 15:34
- 繁花乱开,鸟雀逐风。心自宁静,纷扰不闻。
2023-03-14 09:56
- 对于不可控的事,我们保持乐观,对于可控的事情,我们保持谨慎。
2023-02-09 11:03
- 小时候,
暑假意味着无忧无虑地玩很长一段时间,
节假意味着好吃好喝还有很多长期不见的小朋友来玩...
长大后,
这是女儿第一个暑假,
一个半月...
2022-07-11 08:54
- Watching the autumn leaves falling as you grow older together
2018-10-25 09:45
分类
最新评论
- Goonog
i get it now :) - 萧
@Fluzak:The web host... - Fluzak
Nice blog here! Also... - Albertarive
In my opinion you co... - ChesterHep
What does it plan? - ChesterHep
No, opposite. - mojoheadz
Everything is OK!... - Josephmaigh
I just want to say t... - ChesterHep
What good topic - AnthonyBub
Certainly, never it ...
发表评论: