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

[NOIP2014]寻找道路

题目描述 Description

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

1.路径上的所有点的出边所指向的点都直接或间接与终点连通。

2.在满足条件1的情况下使路径最短。

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

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

输入描述 Input Description

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

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

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

输出描述 Output Description

输出文件名为road.out。

输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出-1。

样例输入 Sample Input


road.in


road.out


3 2

1 2

2 1

1 3


-1

样例输出 Sample Output


road.in


road.out


6 6

1 2

1 3

2 6

2 5

4 5

3 4

1 5


3

数据范围及提示 Data Size & Hint

对于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。

试题分析:反向建边比较好求每个点是否可以经过,DFS跑一遍就可以知道。

然后再忽略不合法的点,跑一遍SPFA           20分钟1A

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
//#include<cmath>

using namespace std;
const int INF = 9999999;
#define LL long long

inline int read(){
	int x=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
	return x*f;
}
int N,M;
int Node[200001],Root[200001],Next[200001];
int cnt; bool vis[10001];
int to[10001]; int dis[10001];
bool inq[10001];int que[10001];
int S,T;

void addedge(int u,int v){
	cnt++;
	Node[cnt]=v;
	Next[cnt]=Root[u];
	Root[u]=cnt;
	return ;
}
void outto(int x){
	vis[x]=true;
	for(int k=Root[x];k;k=Next[k]){
		to[Node[k]]--;
		if(!vis[Node[k]]) outto(Node[k]);
	}
	return ;
}
int SPFA(int s,int t){
	if(!vis[s]||!vis[t]) return -1;
	memset(inq,false,sizeof(inq));
	memset(dis,INF,sizeof(dis));
	dis[s]=0; inq[s]=true; int tail=1; que[tail]=s;
	for(int head=1;head<=tail;head++){
		for(int x=Root[que[head]];x;x=Next[x]){
			if(vis[Node[x]]&&dis[Node[x]]>dis[que[head]]+1){
				dis[Node[x]]=dis[que[head]]+1;
				if(!inq[Node[x]]){
					inq[Node[x]]=true;
					que[++tail]=Node[x];
				}
			}
		}
		inq[que[head]]=false;
	}
	if(dis[t]>=INF) return -1;
	return dis[t];
}

int main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	N=read(),M=read();
	for(int i=1;i<=M;i++){
		int x=read(),y=read();
		addedge(y,x);to[x]++;
	}
	S=read(),T=read();
	outto(T);
	for(int i=1;i<=N;i++)
	    if(!to[i]&&vis[i]==true) vis[i]=true;
	    else vis[i]=false;
	printf("%d\n",SPFA(T,S));
	return 0;
}
时间: 2024-12-13 01:48:22

【DFS】【图论】NOIP2014寻找道路的相关文章

[NOIP2014] 寻找道路

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

[NOIP2014]寻找道路 题解

题目大意: 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条件1 的情况下使路径最短. 思路: 先将与终点相通的点求出来(从终点倒着bfs,再将进入未访问到的点的点踢去),再在部分图跑最短路. 代码: 1 #include<cstdio> 2 const int M=200005,INF=10000000; 3 int cnt,n,m,s,t,i,j,o

Noip2014寻找道路题解

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

【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,之间

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

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

[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 个整数

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

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

【图论】畅通道路 prim Kruskal

最近在整理图论的算法.并且做了一些基础的题来练习,现在做一个总结,然后准备进入下一类算法的复习. 算法这个东西,就是不要害怕去编,哪怕自己只是有一点点理解,有好多点的模糊, 找一道基础的题, 对应着有一种思路解答的,去学习代码,学习里面的思路,并且自己动手跟着敲一敲,慢慢的就会理解了.    不用想着一开始就能够很彻底的理解算法的细节上思想. 理解的时候,从它所要达到的目的去思考, 知道它是要做一个什么事情,这是第一步.后面慢慢的多去练,就会更加深刻的理解里面的思想了,包括细节部分, 也会一点一