题解:P2296 [NOIP2014 提高组] 寻找道路
条件第一步,要能到达 \(t\) 点,建反图跑一遍。记录哪些点可行。
第二步,扫描每个点,若其旁边均为标记过的,说明点的出边所指向的点都直接或间接与终点连通。记录这个点第二次
第三步,在原边枚举每条边,若两个节点均被记录了第二次,加入一个新图,否则扔掉。
对新图进行 BFS 即可。
代码:
#include<bits/stdc++.h>
using namespace std;
int n, m, s, t, vis[10005], can[10005], dis[10005];
vector<int> g[10005], f[10005], h[10005];
void dfs(int u){
vis[u] = 1;
for(int i = 0; i < g[u].size(); i ++){
if(!vis[g[u][i]]){
dfs(g[u][i]);
}
}
}
queue<int> q;
int main(){
cin >> n >> m;
for(int i = 1; i <= m; i ++){
int u, v; cin >> u >> v;
f[u].push_back(v); g[v].push_back(u);
}
cin >> s >> t;
dfs(t);
for(int i = 1; i <= n; i ++){
can[i] = 1;
for(int j = 0; j < f[i].size(); j ++){
can[i] = min(can[i], vis[f[i][j]]);
}
}
for(int i = 1; i <= n; i ++){
for(int j = 0; j < g[i].size(); j ++){
if(can[i] && can[g[i][j]]) h[g[i][j]].push_back(i);
}
}
for(int i = 1; i <= n; i ++) dis[i] = -1;
q.push(s); dis[s] = 0;
while(q.size()){
int now = q.front(); q.pop();
for(int i = 0; i < h[now].size(); i ++){
if(dis[h[now][i]] == -1){
dis[h[now][i]] = dis[now] + 1;
q.push(h[now][i]);
}
}
}
cout << dis[t];
return 0;
}
分类:
题解
posted on 2025-01-11 15:09 zhangzirui66 阅读(9) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!