题解:P14128 [SCCPC 2021] Spicy Restaurant
upd:修改了一个唐比错误。
不吃辣的吓哭了。
题目应该都能看懂吧。
大意就是给定一个无向图,有点值 \(w_i\),给出 \(q\) 组询问,每次给出 \(p, a\),输出从节点 \(p\) 出发到达任意点值不超过 \(a\) 的节点的最短距离。
一个简单的 BFS。使用注意力注意到 \(w_i\) 极小,所以可以遍历每种 \(w\),跑 BFS,求出最短距离,然后输出答案。
Code:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<climits>
#define ll long long
#define ull unsigned long long
#define endl '\n'
#define y1 Y1
#define pii pair<int,int>
#define mkp make_pair
#define debug(x, y) cout << x << " " << y << endl
using namespace std;
inline int read(){
int t = 0, flag = 1;
char a = getchar();
while(!isdigit(a)){
if(a == '-')
flag = -1;
a = getchar();
}
while(isdigit(a))
t = t * 10 + a - '0', a = getchar();
return t * flag;
}
//inline void put(int x){
// if(x < 0) putchar('-'), x = -x;
// if(x < 10) putchar(x + '0');
// else put(x / 10), putchar(x % 10 + '0');
//}
const int N = 1e5 + 5;
vector<int> g[N];
queue<int> s;
int n, m, q, w[N], dis[105][N];
void bfs(int x){
for(int i = 1; i <= n; i++)
if(w[i] <= x){
dis[x][i] = 0;
s.push(i);
}//入队
while(!s.empty()){
int u = s.front();
s.pop();//出队
for(int v : g[u])
if(dis[x][v] > dis[x][u] + 1){//跑最短路
dis[x][v] = dis[x][u] + 1;
s.push(v);
}
}
}
void solve(){
int p = read(), a = read();
if(dis[a][p] == 0x3f3f3f3f)
cout << -1 << endl;//不符合要求的。
else cout << dis[a][p] << endl;
}
signed main(){
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
n = read(), m = read(), q = read();
for(int i = 1; i <= n; i++)
cin >> w[i];
for(int i = 1; i <= m; i++){
int u = read(), v = read();
g[u].push_back(v);
g[v].push_back(u);
} //存图
memset(dis, 0x3f, sizeof dis);
for(int i = 1; i <= 100; i++){//w[i] 小于等于 100,直接遍历。
bfs(i);
for(int j = 1; j <= n; j++)
dis[i][j] = min(dis[i][j], dis[i - 1][j]);
}
while(q--){
solve();
}
return 0;
}

浙公网安备 33010602011771号