【2021四川省赛补题】

Problem L. Spicy Restaurant
题意:
无向图的每个顶点有一个属性 w i w_i wi Q Q Q 个询问,第 i i i 个询问给定顶
p p p 和阈值 a a a,问距离 p p p 最近的 w i ≤ a w_i \leq a wia i i i 距离 p p p 有多远。
1 ≤ w i ≤ 100 1 \leq w_i \leq 100 1wi100
多源BFS
d i s [ i ] [ j ] dis[i][j] dis[i][j]表示从点 i i i到辣度为 j j j的最短火锅店距离
最后对于在 x x x点,能吃辣度为 k k k的人来说,答案是 d i s [ x ] [ j ] ( j ≤ k ) dis[x][j](j \leq k) dis[x][j](jk)
关于输入输出的TLE
记得用 " \ n " "\backslash n" "\n",别用 e n d l endl endl!!!不然会超时!!!

#include<bits/stdc++.h> using namespace std; #define endl "\n" typedef long long ll; const int N = 1e5 + 10; int dis[N][110]; vector<int> v[N]; int m, n, q; int w[N]; void bfs(int x) { queue<int> q; for(int i = 1 ; i <= n ; i++) if(w[i] == x) q.push(i),dis[i][x] = 0; while(q.size()){ auto t = q.front();q.pop(); for(auto u : v[t]) { if(dis[u][x] != 0x3f3f3f3f) continue; dis[u][x] = dis[t][x] + 1; q.push(u); } } } int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); memset(dis,0x3f,sizeof dis); //scanf("%d%d%d",&n,&m,&q); cin >> n >> m >> q; for(int i = 1 ; i <= n ; i++) cin >> w[i];//scanf("%d",&w[i]); for(int i = 0 ; i < m ; i++) { int a,b; //scanf("%d%d",&a,&b); cin >> a >> b; v[a].push_back(b); v[b].push_back(a); } for(int i = 1 ; i <= 100 ; i++) bfs(i); for(int i = 1 ; i <= n ; i++) for(int j = 2 ; j <= 100 ; j++) dis[i][j] = min(dis[i][j],dis[i][j-1]); while(q--) { int i,j; //scanf("%d%d",&i,&j); cin >> i >> j; //printf("%d\n",((dis[i][j]==0x3f3f3f3f)?-1:dis[i][j])); cout << ((dis[i][j]==0x3f3f3f3f)?-1:dis[i][j]) << endl; } }

E Don’t Really Like How The Story Ends
题意:
给出 n n n个点 m m m条边,问需要补充多少条边使得能够依次DFS遍历到顶点 1 − n 1-n 1n
思路:

  1. 如果 v v v v + 1 v + 1 v+1直接相连,则访问搜索 v + 1 v + 1 v+1
  2. 如果 v v v点存在没有访问的相邻节点且 v v v点不与 v + 1 v + 1 v+1点相连,此时必须将 v + 1 v + 1 v+1 连接到 v v v
  3. 如果 v v v 点所有相邻节点都被访问了, v + 1 v+1 v+1可以与 v v v相连,也可以和从 1 = > v 1 => v 1=>v中路径上的任意一点相连,路径上的点都在递归栈里面,此时可以让 v v v点退栈,一直回到某个满足条件 1 1 1 2 2 2的节点
  4. 如果第 3 3 3点的点退栈一直到起点 1 1 1号点都没有直接相连,说明存在不连通部分,此时必须加边,此时再去搜索不连通的部分,一直到全部搜索完
#include<bits/stdc++.h> using namespace std; const int N = 1e5 + 10; int n, m, vis[N]; vector<int> e[N]; int ans, ne; void dfs(int u) { ne ++; for(int i = 0 ; i < e[u].size() ; i++) { int v = e[u][i]; if(vis[v]) continue; if(v == ne) { vis[ne] = 1; //cout << "case1:" << u << " " << v << " " << ne << '\n'; dfs(ne); }else { ans++; vis[ne] = 1; //cout << "case2:" << u << " " << v << " " << ne << '\n'; dfs(ne); i--;//表示并没有使用u->v这条边 所以要重新看一次这条边 } } //如果遍历完了所有出边 最终走到了ne 但ne并不是n 说明并不联通 需要继续连边 if( u == 1 ){ while(ne <= n){ vis[ne] = 1; //cout << "case3:" << u << " " << ne << '\n'; dfs(ne); ans++; } } } void solve() { cin >> n >> m; ans = 0, ne = 1; for(int i = 1 ; i <= n ; i++) { e[i].clear(); vis[i] = 0; } for(int i = 0 ; i < m ; i++) { int a, b; cin >> a >> b; if(a > b) e[b].push_back(a); else e[a].push_back(b); } for(int i = 1 ; i <= n ; i++) sort(e[i].begin(), e[i].end()); vis[1] = 1; dfs(1); cout << ans << "\n"; } int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); int _; cin >> _; while(_--) solve(); return 0; }

__EOF__

本文作者xued
本文链接https://www.cnblogs.com/xdeyt/p/18140586.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   xde_yt  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示