首页 > 其他分享 >[NOIP 2014] 寻找道路

[NOIP 2014] 寻找道路

时间:2024-05-27 20:59:11浏览次数:19  
标签:10005 终点 NOIP int 路径 样例 寻找 2014 dis

[NOIP 2014] 寻找道路

在有向图 G 中,每条边的长度均为 11,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:

  1. 路径上的所有点的出边所指向的点都直接或间接与终点连通。
  2. 在满足条件 11 的情况下使路径最短。

注意:图 G 中可能存在重边和自环,题目保证终点没有出边。

请你输出符合条件的路径的长度。

0<n≤10,000,0<m≤200,000,0<x,y,s,t≤n,x≠t。

样例输入 1

3 2
1 2
2 1
1 3

样例输出 1

-1

样例解释 1

如上图所示,箭头表示有向道路,圆点表示城市。起点 1 与终点 3 不连通,所以满足题目描述的路径不存在,故输出 −1。

样例输入 2

6 6
1 2
1 3
2 6
2 5
4 5
3 4
1 5

样例输出 2

3

样例解释 2


如上图所示,满足条件的路径为 1→3→4→5。注意点 2 不能在答案路径中,因为点 2 连了一条边到点 6,而点 6 不与终点 5 连通。

题解

我们需要关注有哪些点是直接或间接与终点相连的,这就可以建立反向图由终点开始搜索了,DFS 或 BFS 都可以。

然后看每个点,看每个点连出的每条边,如果发现这个点连着一个刚才没有被标记的点,就说明这个点是不符合题目要求的点,就不能用。

最后在正向图上 BFS,只走符合要求的点。

#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
vector<int> G1[10005], G2[10005];
bool vis[10005], f[10005];
int dis[10005];
int n, m, s, t;
void dfs(int u) {
    vis[u] = true;
    for (int i = 0; i < G2[u].size(); i++) {
        int v = G2[u][i];
        if (!vis[v]) {
            dfs(v);
        }
    }
}
queue<int> q;
void bfs(int s) {
    memset(dis, -1, sizeof(dis));
    dis[s] = 0;
    q.push(s);
    while (!q.empty()) {
        int now = q.front();
        q.pop();
        for (int i = 0; i < G1[now].size(); i++) {
            int v = G1[now][i];
            if (f[v] && dis[v] == -1) {
                dis[v] = dis[now] + 1;
                q.push(v);
            }
        }
    }
}
int main() {
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        G1[u].push_back(v);
        G2[v].push_back(u);
    }
    cin >> s >> t;
    dfs(t);
    for(int i = 1; i <= n; i++){
        f[i] = true;
    }
    for(int i = 1;i <= n; i++){
        for(int j = 0; j < G1[i].size(); j++){
            int v = G1[i][j];
            if (!vis[v]){
                f[i] = false;
            }
        }
    }
    bfs(s);
    cout << dis[t] << endl;
    return 0;
}

标签:10005,终点,NOIP,int,路径,样例,寻找,2014,dis
From: https://blog.csdn.net/yymer214/article/details/139072505

相关文章

  • CSP历年复赛题-P1057 [NOIP2008 普及组] 传球游戏
    原题链接:https://www.luogu.com.cn/problem/P1057题意解读:n个人围一圈,从1开始传球m次,每次可以往左或右传,计算球再次传给1的方案数。解题思路:求方案数,通常就是DP问题,此题DP状态并不难想,如果实在不会,也可以通过DFS暴搜得部分分。1、DFS60分代码:#include<bits/stdc++.h>using......
  • CSP历年复赛题-P1055 [NOIP2008 普及组] ISBN 号码
    原题链接:https://www.luogu.com.cn/problem/P1055题意解读:验证ISBN最后一位是否正确。解题思路:直接模拟,不多说,上代码。100分代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;cin>>s;intcode=0;intcnt=0;for(inti......
  • 【c++提高组】津津的储蓄计划(NOIP2004)
    题目描述津津的零花钱一直都是自己管理。每个月的月初妈妈给津津 300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同。为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里,到了年末她会加上 20%还给津津。因此津津制定了一个储蓄计划:每个月的......
  • Leetcode 1971. 寻找图中是否存在路径
    有一个具有n个顶点的双向图,其中每个顶点标记从0到n-1(包含0和n-1)。图中的边用一个二维整数数组edges表示,其中edges[i]=[ui,vi]表示顶点ui和顶点vi之间的双向边。每个顶点对由最多一条边连接,并且没有顶点存在与自身相连的边。请你确定是否存在从......
  • CSP历年复赛题-P1096 [NOIP2007 普及组] Hanoi 双塔问题
    原题链接:https://www.luogu.com.cn/problem/P1096题意解读:汉诺双塔的移动次数,与经典汉诺塔的区间在于同一个尺寸盘子有两个。解题思路:可以直接用经典汉诺塔方法来计算,双塔的结果就最终乘以2即可。首先想到的是递归,但是由于数据量n最大200,递归会超时,但是50%的样例应该没问题,先......
  • # [NOIP2014 提高组] 生活大爆炸版石头剪刀布
    传送锚点:https://www.luogu.com.cn/problem/P1328题目背景NOIP2014提高组D1T1题目描述石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第8集中出现了一种石头剪刀布的升级版游戏。升级版游戏在传统的石头......
  • 【NOIP2015普及组复赛】题3:求和
    题3:求和【题目描述】一条狭长的纸带被均匀划分出了nnn个格子,格子编号从11......
  • 【NOIP2015普及组复赛】题4:推销员
    题4:推销员【题目描述】阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有NNN家......
  • P1048 [NOIP2005 普及组] 采药
    ##题目描述辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价......
  • CSP历年复赛题-P1095 [NOIP2007 普及组] 守望者的逃离
    原题链接:https://www.luogu.com.cn/problem/P1095题意解读:在有限的时间内,通过跑步或者闪烁两种方式,能跑出的最远距离是多少,以及是否能跑出出口。解题思路:1、贪心法每一秒钟,都有两种选择:跑步(17米)、闪烁(60米,前提是蓝够10点,否则等待1s恢复4点蓝)经过计算,恢复足够的蓝到闪烁需要3.......