描述

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

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

注意:图 G 中可能存在重边和自环,题目保证终点没有出边。 请你输出符合条件的路径的长度。

格式

输入格式

第一行有两个用一个空格隔开的整数 n 和 m,表示图有 n 个点和 m 条边。

接下来的 m 行每行 2 个整数 x、y,之间用一个空格隔开,表示有一条边从点 x 指向点y。

最后一行有两个用一个空格隔开的整数 s、t,表示起点为 s,终点为 t。

输出格式

输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。

如果这样的路径不存在,输出-1。

样例1

样例输入1[复制]

 
3 2
1 2
2 1
1 3

样例输出1[复制]

 
-1

样例2

样例输入2[复制]

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

样例输出2[复制]

 
3

限制

对于 30%的数据,0 < n ≤ 10,0 < m ≤ 20;

对于 60%的数据,0 < n ≤ 100,0 < m ≤ 2000;

对于 100%的数据,0 < n ≤ 10,000,0 < m ≤ 200,000,0 < x,y,s,t ≤ n,x ≠ t。

提示

【输入输出样例1说明】

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

【输入输出样例2说明】

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

来源

NOIP2014 提高组 Day2


一开始错解题意了,以为只要是能到那些不连通终点的点的所有点都不能要,就全W了

后来才明白只用找和这些达不到终点的点直接相连的点就可以了,都是语文太差了。。。

方法很简单

就是先反向存图,从终点开始dfs一次把终点不能到的点标记出来

然后把所有和这些点直接相连的点也标记了,最后来一遍bfs

AC代码

 #include<queue>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#define MAX 2000005
using namespace std;
int n,m;
int tot;
int s,t;
int ans;
int totz;
int v1,v2;
struct xx{int num,step;};
queue<xx>way;
int vis[];
int vis2[];
int innum[];
int cannot[];
int outnum[];//出度
int head[],next[MAX],tov[MAX];
int headz[],nextz[MAX],tovz[MAX];
void add(int a,int b)
{
tot++;
tov[tot]=b;
next[tot]=head[a];
head[a]=tot;
}
void addz(int a,int b)
{
totz++;
tovz[totz]=b;
nextz[totz]=headz[a];
headz[a]=tot;
}
void dfs(int k)
{
if(vis[k])return;
vis[k]=;
for(int i=head[k];i;i=next[i])
dfs(tov[i]);
}
void del(int k)
{
cannot[k]=;
for(int i=head[k];i;i=next[i])
if(!cannot[tov[i]])
cannot[tov[i]]=;
}
void BFS()
{
xx des,v,u;
des.num=s;
des.step=;
way.push(des);
while(!way.empty())
{
u=way.front();
way.pop();
for(int i=headz[u.num];i;i=nextz[i])
if(!vis2[tovz[i]]&&!cannot[tovz[i]])
{
v.num=tovz[i];
vis2[v.num]=;
v.step=u.step+;
if(v.num==t)
{
cout<<v.step;
exit();
}
way.push(v);
}
}
}
int main()
{
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
cin>>n>>m;
for(int i=;i<=m;i++)
{
scanf("%d%d",&v1,&v2);
if(v2!=v1)//自环
{
add(v2,v1);//反存边
addz(v1,v2);
outnum[v1]++;
innum[v2]++;
}
}
cin>>s>>t;
//if(s==t){cout<<"0";return 0;}
//if(outnum[s]==0||innum[t]==0){cout<<"-1";return 0;}
dfs(t);//从终点出发扩展一次找出不能直接或间接到终点的点
//if(!vis[s]){cout<<"-1";return 0;}
for(int i=;i<=n;i++)
if(!vis[i]&&!cannot[i])
del(i);
cannot[s]=;//起点必须可以走
BFS();
cout<<"-1";
return ;
}

vijos1909寻找道路的更多相关文章

  1. NOIP2014 寻找道路

    2.寻找道路 (road.cpp/c/pas) [问题描述] 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1.路径上的所有点的出边所指 ...

  2. Codevs 3731 寻找道路 2014年 NOIP全国联赛提高组

    3731 寻找道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找 ...

  3. 洛谷P2296 寻找道路 [拓扑排序,最短路]

    题目传送门 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点 ...

  4. 【DFS】【图论】NOIP2014寻找道路

    [NOIP2014]寻找道路 题目描述 Description 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1.路径上的所有点的出边所 ...

  5. 【洛谷P2296】[NOIP2014]寻找道路

    寻找道路 题目链接 这道题非常的水,按照题意, 先反向建边,从终点搜索,标记出可以到达终点的点 然后枚举一遍,判断出符合条件1的点 再从起点搜索一遍就可以了 #include<iostream& ...

  6. 洛谷P2296 寻找道路==codevs3731 寻找道路

    P2296 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点 ...

  7. noip寻找道路

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  8. 洛谷——P2296 寻找道路

    P2296 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点 ...

  9. luogu 2296 寻找道路 (搜索)

    luogu 2296 寻找道路 题目链接:https://www.luogu.org/problemnew/show/P2296 从终点bfs或者dfs,找出所有终点能到达的点. 然后再从1到n看一下 ...

随机推荐

  1. shell脚本中的反引号使用 `

    反引号是~的英文切换 在shell脚本中,反引号允许将shell命令的输出赋值给变量. test=`date` 这样shell会执行反引号中的命令.并将执行的结果赋值给变量tests.

  2. java解析中国行政区域并在页面显示实现动态逐级筛选

    一.实现目标 首先会有一个存放中国行政区域数据的一个txt文件,用java读取并解析出来,并在页面上通过下拉框的形式展示出来.实现效果如下图,当选择完省份后,在选择该省份下的城市,然后在选择该城市下的 ...

  3. HTML 导航框架 (使用 Frame )

    文章出处  :  http://blog.sina.com.cn/s/blog_6f6d07f80100oqlt.html  (本文转自此博客) 在浏览网页时,我们经常会看到一个导航条,当点击导航条上 ...

  4. Hibernate 注解的用法以及说明

    1.类级别注解 @Entity     映射实体类 @Table    映射数句库表  @Entity(name="tableName") - 必须,注解将一个类声明为一个实体be ...

  5. 06Java数组

    动手动脑: import java.io.*; public class QiPan { //定义一个二维数组来充当棋盘 private String[][] board; //定义棋盘的大小 pri ...

  6. redis cluster java client jedisCluster spring集成方法

    1.使用jedis的原生JedisCluster spring的applicationContext.xml配置redis的连接.连接池.jedisCluster Bean <bean id=& ...

  7. (一)startup.bat

    那么startup.bat(// TODO startup.sh暂缓)启动后发生了什么呢? @echo off rem Licensed to the Apache Software Foundati ...

  8. python迭代器和生成器

    迭代器 #可以被netxt()函数调用不断返回一个值的对象成为迭代器:Iterator #迭代器是访问集合元素的一种方式,从集合第一个元素开始(用next()方法)访问就不能回退,便于循环遍历一些较大 ...

  9. sublime插件 TortioseSVN

    TortioseSVN 可以安装在sublime中,实现svn文件的增加.删除.更新.提交等功能(TortioseSVN用在window系统中,linux安装svn) 安装: 首先在sublime中搜 ...

  10. 基类用的this指针

    结论:基类构造函数中的this指针指向的是派生类的对象 测试代码: #include <iostream> using namespace std; class father; fathe ...