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

寻找道路

题目链接

这道题非常的水,按照题意,

先反向建边,从终点搜索,标记出可以到达终点的点

然后枚举一遍,判断出符合条件1的点

再从起点搜索一遍就可以了

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 #define N 10010
 6 #define M 200010
 7 int n,m,Head[N],_Head[N],dis[N],tot,s,t;
 8 int que[M],head,tail;
 9 bool vis[N],ok[N];
10 inline int read(){
11     int x=0; char c=getchar();
12     while(c<'0'||c>'9') c=getchar();
13     while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
14     return x;
15 }
16 struct NODE{
17     int to,next;
18 } e[M],_e[M];
19 inline void add(int x,int y){
20     e[++tot].to=y;
21     e[tot].next=Head[x];
22     Head[x]=tot;
23     _e[tot].to=x;
24     _e[tot].next=_Head[y];
25     _Head[y]=tot;
26 }
27 int main()
28 {
29     n=read(); m=read();
30     int x,y;
31     for(int i=1;i<=m;i++){
32         x=read(); y=read();
33         add(x,y);
34     }
35     s=read(); t=read();
36     que[++tail]=t; vis[t]=1;
37     while(head<tail){
38         int u=que[++head];
39         for(int i=_Head[u];i;i=_e[i].next){
40             int v=_e[i].to;
41             if(!vis[v]){
42                 vis[v]=1;
43                 que[++tail]=v;
44             }
45         }
46     }
47     for(int i=1;i<=n;i++){
48         bool flag=1;
49         for(int j=Head[i];j;j=e[j].next)
50          if(!vis[e[j].to]) {
51              flag=0; break;
52          }
53         ok[i]=flag;
54     }
55     head=tail=0;
56     que[++tail]=s;
57     dis[s]=1;
58     while(head<tail){
59         int u=que[++head];
60         if(u==t) break;
61         for(int i=Head[u];i;i=e[i].next){
62             int v=e[i].to;
63             if(!dis[v]&&ok[v]){
64                 dis[v]=dis[u]+1;
65                 que[++tail]=v;
66             }
67         }
68     }
69     if(dis[t])
70         printf("%d\n",dis[t]-1);
71     else
72         puts("-1");
73     return 0;
74 }

 

posted @ 2018-07-17 21:09  yjk  阅读(132)  评论(0编辑  收藏  举报