vijos1909寻找道路

描述

在有向图 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代码

  1 #include<queue>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<iostream>
  5 #define MAX 2000005
  6 using namespace std;
  7 int n,m;
  8 int tot;
  9 int s,t;
 10 int ans;
 11 int totz;
 12 int v1,v2;
 13 struct xx{int num,step;};
 14 queue<xx>way;
 15 int vis[10005];
 16 int vis2[10005];
 17 int innum[10005];
 18 int cannot[10005];
 19 int outnum[10005];//出度
 20 int head[10005],next[MAX],tov[MAX];
 21 int headz[10005],nextz[MAX],tovz[MAX];
 22 void add(int a,int b)
 23 {
 24     tot++;
 25     tov[tot]=b;
 26     next[tot]=head[a];
 27     head[a]=tot;
 28 }
 29 void addz(int a,int b)
 30 {
 31     totz++;
 32     tovz[totz]=b;
 33     nextz[totz]=headz[a];
 34     headz[a]=tot;
 35 }
 36 void dfs(int k)
 37 {
 38     if(vis[k])return;
 39     vis[k]=1;
 40     for(int i=head[k];i;i=next[i])
 41         dfs(tov[i]);
 42 }
 43 void del(int k)
 44 {
 45     cannot[k]=1;
 46     for(int i=head[k];i;i=next[i])
 47     if(!cannot[tov[i]])
 48         cannot[tov[i]]=1;
 49 }
 50 void BFS()
 51 {
 52     xx des,v,u;
 53     des.num=s;
 54     des.step=0;
 55     way.push(des);
 56     while(!way.empty())
 57     {
 58         u=way.front();
 59         way.pop();
 60         for(int i=headz[u.num];i;i=nextz[i])
 61         if(!vis2[tovz[i]]&&!cannot[tovz[i]])
 62         {
 63             v.num=tovz[i];
 64             vis2[v.num]=1;
 65             v.step=u.step+1;
 66             if(v.num==t)
 67             {
 68                 cout<<v.step;
 69                 exit(0);
 70             }
 71             way.push(v);
 72         }
 73     }
 74 }
 75 int main()
 76 {
 77     freopen("road.in","r",stdin);
 78     freopen("road.out","w",stdout);
 79     cin>>n>>m;
 80     for(int i=1;i<=m;i++)
 81     {
 82         scanf("%d%d",&v1,&v2);
 83         if(v2!=v1)//自环
 84         {
 85             add(v2,v1);//反存边
 86             addz(v1,v2);
 87             outnum[v1]++;
 88             innum[v2]++;
 89         }
 90     }
 91     cin>>s>>t;
 92     //if(s==t){cout<<"0";return 0;}
 93     //if(outnum[s]==0||innum[t]==0){cout<<"-1";return 0;}
 94     dfs(t);//从终点出发扩展一次找出不能直接或间接到终点的点
 95     //if(!vis[s]){cout<<"-1";return 0;}
 96     for(int i=1;i<=n;i++)
 97     if(!vis[i]&&!cannot[i])
 98         del(i);
 99     cannot[s]=0;//起点必须可以走
100     BFS();
101     cout<<"-1";
102     return 0;
103 }

时间: 2024-10-05 20:59:47

vijos1909寻找道路的相关文章

Vijos1909 寻找道路

思路:这题嘛,边权都为1了还让求最短路,没别的,肯定bfs.对于哪些点能走,哪些点不能走,只需从终点对逆图进行bfs最后再对每个点一一检查就行了.但需要注意的一点是,图中存在环,在bfs时要打上访问标记(否则就是TLE+MLE,惨痛的教训--). 代码如下: #include<iostream> #include<cstdio> #include<queue> #include<vector> #include<cstring> using na

P2296 寻找道路

P2296 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条件1 的情况下使路径最短. 注意:图G 中可能存在重边和自环,题目保证终点没有出边. 请你输出符合条件的路径的长度. 输入输出格式 输入格式: 输入文件名为road .in. 第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边. 接下来的m 行每行2 个整数

【NOIP之旅】NOIP2014 day2 T2 寻找道路

2.寻找道路 (road.cpp/c/pas) [问题描述] 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1.路径上的所有点的出边所指向的点都直接或间接与终点连通. 2.在满足条件1的情况下使路径最短. 注意:图G中可能存在重边和自环,题目保证终点没有出边. 请你输出符合条件的路径的长度. [输入] 输入文件名为road.in. 第一行有两个用一个空格隔开的整数n和m,表示图有n个点和m条边. 接下来的m行每行2个整数x.y,之间

寻找道路——呆滞大佬der最骚暴力

寻找道路 题目描述: 有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条件1 的情况下使路径最短. 注意:图G 中可能存在重边和自环,题目保证终点没有出边. 请你输出符合条件的路径的长度. 输入格式: 第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边. 接下来的m 行每行2 个整数x .y ,之间用一个空格隔开,表示有一条边从点x 指向点y . 最后一行有两个用一个空格隔开的整数s .t ,表示起点为s ,终点为t . 输出格式: 输出只有一行,包含一个整数,表示

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

[NOIP2014]寻找道路 题目描述 Description 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1.路径上的所有点的出边所指向的点都直接或间接与终点连通. 2.在满足条件1的情况下使路径最短. 注意:图G中可能存在重边和自环,题目保证终点没有出边. 请你输出符合条件的路径的长度. 输入描述 Input Description 第一行有两个用一个空格隔开的整数n和m,表示图有n个点和m条边. 接下来的m行每行2个整数x.

[FZYZOJ 2047] [NOIP2014 D2T2] 寻找道路

[NOIP2014_D2_T2]寻找道路 时间限制:1000MS 内存限制:131072KB Description 在有向图 G 中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1.路径上的所有点的出边所指向的点都直接或间接与终点连通. 2.在满足条件 1 的情况下使路径最短. 注意:图 G 中可能存在重边和自环,题目保证终点没有出边. 请你输出符合条件的路径的长度. Input Format 第一行有两个用一个空格隔开的整数 n 和 m,

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

P2296 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条件1 的情况下使路径最短. 注意:图G 中可能存在重边和自环,题目保证终点没有出边. 请你输出符合条件的路径的长度. 输入输出格式 输入格式: 输入文件名为road .in. 第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边. 接下来的m 行每行2 个整数

[UOJ] #19 寻找道路

#19. 寻找道路NOIP2014 在有向图 GG 中,每条边的长度均为 11,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 路径上的所有点的出边所指向的点都直接或间接与终点连通. 在满足条件 1 的情况下使路径最短. 注意:图 GG 中可能存在重边和自环,题目保证终点没有出边. 请你输出符合条件的路径的长度. 输入格式 第一行有两个用一个空格隔开的整数 nn 和 mm,表示图有 nn 个点和 mm 条边. 接下来的 mm 行每行 22 个整数 x,yx,y,之间用

洛谷——P2296 寻找道路

P2296 寻找道路 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条件1 的情况下使路径最短. 注意:图G 中可能存在重边和自环,题目保证终点没有出边. 请你输出符合条件的路径的长度. 输入输出格式 输入格式: 输入文件名为road .in. 第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边. 接下来的m 行每行2 个整数