Spicy Restaurant
做题时的思路是正序思路,也就是从每个顾客开始找最短的距离,但考虑到数据量的大小肯定会爆。于是考虑逆向思考,即对所有辣度相同的饭店进行预处理,更新完所有的点,最后进行求值。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int dis[N][110], head[N], w[N], tot, n, m, q;
bool vis[N];
struct Edge{
int u, next, v, w;
}edge[N * 2];
void add(int u, int v){
edge[tot].next = head[u];
edge[tot].v = v;
head[u] = tot ++;
}
void bfs(int s){
queue<int> q;
for(int i = 1; i <= n; i ++){ //将辣度相同的饭店都放到待更新队列里
if(w[i] == s){
q.push(i);
vis[i] = true;
dis[i][s] = 0; //初始化为0
}
}
while(q.size()){
int t = q.front();
q.pop();
//更新该店铺的所有临边
for(int i = head[t]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(vis[v])
continue;
vis[v] = true;
dis[v][s] = dis[t][s] + 1; //当前点到辣度为s的饭店的最短距离为上一个点的最短距离+1
q.push(v); //放入队列等待下次更新
}
}
}
int main(){
scanf("%d%d%d", &n, &m, &q);
memset(head, -1, sizeof head);
memset(dis, -1, sizeof dis);
for(int i = 1; i <= n; i ++)
scanf("%d", &w[i]);
for(int i = 1; i <= m; i ++){
int u, v;
scanf("%d%d", &u, &v);
if(u == v)
continue;
add(u, v);
add(v, u);
}
for(int i = 100; i >= 1; i --){
memset(vis, 0, sizeof vis);
bfs(i);
}
for(int i = 1; i <= q; i ++){
int pos, capa, minn = 0x3f3f3f3f;
scanf("%d%d", &pos, &capa);
for(int i = 1; i <= capa; i ++) //从所有符合条件的饭店中找打一个最近的
if(dis[pos][i] != -1)
minn = min(minn, dis[pos][i]);
if(minn == 0x3f3f3f3f)//如果没有就是-1
minn = -1;
printf("%d\n", minn);
}
return 0;
}