vijos1909【noip2014】寻找道路

来源:互联网 发布:切割大小头怎样编程 编辑:程序博客网 时间:2024/05/21 12:43

描述

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

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

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

格式

输入格式

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

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

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

输出格式

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

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

样例1

样例输入1[复制]

3 21 22 11 3

样例输出1[复制]

-1

样例2

样例输入2[复制]

6 61 21 32 62 54 53 41 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




因为每条边长度为1,所以可以两次BFS求最短路径。

第一次从终点BFS,判断每个点是否与终点连通,并且判断每个点是否为好点。第二次从起点BFS,求得最短路径。

最初我写的BFS一直在T...到现在也不知道为什么





#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#define F(i,j,n) for(int i=j;i<=n;i++)#define D(i,j,n) for(int i=j;i>=n;i--)#define LL long long#define MAXM 400005#define MAXN 10005#define INF 1000000000using namespace std;struct edge_type{int next,to;}e[MAXM];int n,m,x[MAXM],y[MAXM],s,t,head[MAXN],dis[MAXN],cnt=0;bool f[MAXN];queue<int> q;int read(){int ret=0;char ch=getchar();while (ch<'0'||ch>'9') ch=getchar();while (ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}return ret;}void add_edge(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}void bfs(int u,int flag){memset(dis,-1,sizeof(dis));q.push(u);dis[u]=0;while (!q.empty()){int tmp=q.front();q.pop();for(int p=head[tmp];p;p=e[p].next) if (p%2==flag&&!f[e[p].to]){int to=e[p].to;if (dis[to]==-1){dis[to]=dis[tmp]+1;q.push(to);}}}}int main(){freopen("input.in","r",stdin);memset(head,0,sizeof(head));memset(f,false,sizeof(f));n=read(); m=read();F(i,1,m){x[i]=read(); y[i]=read();add_edge(x[i],y[i]);add_edge(y[i],x[i]);}s=read(); t=read();bfs(t,0);F(i,1,m) if (dis[y[i]]==-1) f[x[i]]=true;if (f[s]){printf("-1\n");return 0;}bfs(s,1);printf("%d\n",dis[t]);return 0;}


0 0