P2296 寻找道路
寻找道路
这个题是14年day2的第二题,也只有普及+/提高的难度。
题目大意就是在一堆满足所有后继连接的点都可以到达终点的点中,找到最短路径。
思路就是先一边dfs,求出满足条件1的点,之后spfa就好了,其实用bfs会更快一点。
代码:
1 #include<queue> 2 #include<cstdio> 3 #define N 10010 4 #define M 200020 5 int next1[M],to1[M],num1,head1[N],next2[M],to2[M],num2,head2[N],vis[N],dis[N],n,m,a,b,qd,zd,flag; 6 bool boo[N],exist[N]; 7 void add1(int false_from,int false_to){ 8 next1[++num1]=head1[false_from]; 9 to1[num1]=false_to; 10 head1[false_from]=num1; 11 } 12 void add2(int false_from,int false_to){ 13 next2[++num2]=head2[false_from]; 14 to2[num2]=false_to; 15 head2[false_from]=num2; 16 } 17 void dfs(int u){ 18 if(u==qd) 19 flag = 1; 20 vis[u]=1; 21 for(int i=head2[u];i;i=next2[i]) 22 if(!vis[to2[i]]) 23 dfs(to2[i]); 24 } 25 void spfa(int x){ 26 std::queue<int>q; 27 q.push(x); 28 exist[x]=1; 29 dis[x]=0; 30 while(!q.empty()){ 31 int u=q.front(); 32 q.pop(); 33 exist[u]=0; 34 for(int i=head1[u];i;i=next1[i]) 35 if(dis[to1[i]]>dis[u]+1&&boo[to1[i]]&&boo[u]){ 36 dis[to1[i]]=dis[u]+1; 37 if(!exist[to1[i]]){ 38 q.push(to1[i]); 39 exist[to1[i]]=1; 40 } 41 } 42 } 43 } 44 int main(){ 45 scanf("%d%d",&n,&m); 46 for(int i=1;i<=m;++i){ 47 scanf("%d%d",&a,&b); 48 add1(a,b); 49 add2(b,a); 50 } 51 scanf("%d%d",&qd,&zd); 52 dfs(zd); 53 if(!flag){ 54 printf("-1"); 55 return 0; 56 } 57 for(int i=1;i<=n;++i) 58 boo[i]=1; 59 for(int i=1;i<=n;i++) 60 if(!vis[i]){ 61 boo[i]=0; 62 for(int j=head2[i];j;j=next2[j]) 63 boo[to2[j]]=0; 64 } 65 for(int i=1;i<=n;++i) 66 dis[i]=42000000; 67 boo[zd]=1; 68 spfa(qd); 69 if(dis[zd]!=42000000) 70 printf("%d\n",dis[zd]); 71 else 72 printf("-1\n"); 73 return 0; 74 }