【洛谷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 }