TOJ 9

TOJ 9

題敘

https://toj.tfcis.org/oj/pro/9/
給一張圖,有兩種遍歷方式,給定起點與終點高度,求兩種遍歷方式的時間差
終點為該圖的最低高度點,可能有多個

  1. 坐下坡車
    每經過一條路需花 $1$ 分鐘
    每次只能走向下最陡的路
    如果四周都比該點高,則無法通行
  2. 走路
    每經過一條路需花 $6$ 分鐘
    想怎麼走就怎麼走

想法

從起點開始做兩次 BFS

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//By Koios1143
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define ll long long
#define pii pair<int,int>
using namespace std;
int t,n,m,s,h[10010],Goal=2147483647;
vector<int> nxt[10010];
bool inq[10010];
int get_car_time(){
queue<pii> q;
for(int i=0 ; i<10010 ; i++) inq[i]=false;
q.emplace(s,0);inq[s]=true;
while(!q.empty()){
int now,r;
tie(now,r)=q.front();q.pop();
if(h[now] == Goal){
return r*1;
}
int Max=0;
for(int i=0 ; i<nxt[now].size() ; i++)
Max=max(Max,h[now]-h[nxt[now][i]]);
for(auto i : nxt[now]){
if(h[now]-h[i]==Max && !inq[i]){
q.emplace(i,r+1);
inq[i]=true;
}
}
}
return -1;
}
int get_walk_time(){
queue<pii> q;
for(int i=0 ; i<10010 ; i++) inq[i]=false;
q.emplace(s,0);inq[s]=true;
while(!q.empty()){
int now,r;
tie(now,r)=q.front();q.pop();
if(h[now]==Goal){
return r*6;
}
for(int i=0 ; i<nxt[now].size() ; i++){
if(!inq[nxt[now][i]]){
q.emplace(nxt[now][i],r+1);
inq[nxt[now][i]]=true;
}
}
}
return -1;
}
int main(){
IOS;
cin>>t;
for(int i=1 ; i<=t ; i++){
for(int i=0 ; i<10010 ; i++){
nxt[i].clear();
}
Goal=2147483647;
cin>>n>>m>>s;
for(int i=0 ; i<n ; i++){
cin>>h[i];
Goal=min(Goal,h[i]);
}
for(int i=0,u,v ; i<m ; i++){
cin>>u>>v;
nxt[u].emplace_back(v);
nxt[v].emplace_back(u);
}
int car=get_car_time();
int walk=get_walk_time();
cout<<"Case #"<<i<<": ";
if(car==-1 && walk==-1)
cout<<"Call 119!\n";
else if(car==-1)
cout<<walk<<"\n";
else
cout<<abs(car-walk)<<'\n';
}
return 0;
}

複雜度

最糟的情況是將整張圖都走過一次
複雜度 $O(TN)$