寻找道路
题目描述
在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:
1 .路径上的所有点的出边所指向的点都直接或间接与终点连通。
2 .在满足条件1 的情况下使路径最短。
注意:图G 中可能存在重边和自环,题目保证终点没有出边。
请你输出符合条件的路径的长度。
输入输出格式
输入格式:输入文件名为road .in。
第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边。
接下来的m 行每行2 个整数x 、y ,之间用一个空格隔开,表示有一条边从点x 指向点y 。
最后一行有两个用一个空格隔开的整数s 、t ,表示起点为s ,终点为t 。
输出格式:输出文件名为road .out 。
输出只有一行,包含一个整数,表示满足题目᧿述的最短路径的长度。如果这样的路径不存在,输出- 1 。
输入输出样例
输入样例#1:
3 2 1 2 2 1 1 3
输出样例#1:
-1
输入样例#2:
6 6 1 2 1 3 2 6 2 5 4 5 3 4 1 5
输出样例#2:
3
说明
解释1:
如上图所示,箭头表示有向道路,圆点表示城市。起点1 与终点3 不连通,所以满足题
目᧿述的路径不存在,故输出- 1 。
解释2:
如上图所示,满足条件的路径为1 - >3- >4- >5。注意点2 不能在答案路径中,因为点2连了一条边到点6 ,而点6 不与终点5 连通。
对于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 #include<cstdio> 2 #include<cstring> 3 const int maxn=1e4+10; 4 const int maxm=2e5+10; 5 inline int min_(int x,int y){return x<y?x:y;} 6 int n,m; 7 int s,t; 8 int h[maxn],hs; 9 int et[maxm],en[maxm],ld[maxn]; 10 void add(int u,int v){ 11 hs++,et[hs]=v,en[hs]=h[u],h[u]=hs; 12 ld[v]++; 13 } 14 bool vis[maxn]; 15 void dfs1(int k){ 16 vis[k]=1; 17 for(int i=h[k];i;i=en[i]){ 18 if(!vis[et[i]]) dfs1(et[i]); 19 ld[et[i]]--; 20 } 21 } 22 int d[maxn]; 23 void dfs2(int k){ 24 for(int i=h[k];i;i=en[i]) 25 if(ld[et[i]]==0&&d[k]+1<d[et[i]]){ 26 d[et[i]]=d[k]+1; 27 dfs2(et[i]); 28 } 29 } 30 int main(){ 31 scanf("%d%d",&n,&m); 32 int a,b; 33 for(int i=1;i<=m;i++){ 34 scanf("%d%d",&a,&b); 35 if(a!=b) add(b,a); 36 } 37 scanf("%d%d",&s,&t); 38 dfs1(t); 39 memset(d,0x7f,sizeof(d)); 40 d[t]=0; 41 dfs2(t); 42 if(d[s]==d[0]) puts("-1"); 43 else printf("%d\n",d[s]); 44 return 0; 45 }
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=1e4+10; 4 const int maxm=2e5+10; 5 inline int min_(int x,int y){return x<y?x:y;} 6 int n,m; 7 int s,t; 8 int h[maxn],hs; 9 int et[maxm],en[maxm],ld[maxn]; 10 void add(int u,int v){ 11 hs++,et[hs]=v,en[hs]=h[u],h[u]=hs; 12 ld[v]++; 13 } 14 bool vis[maxn]; 15 void dfs1(int k){ 16 vis[k]=1; 17 for(int i=h[k];i;i=en[i]){ 18 if(!vis[et[i]]) dfs1(et[i]); 19 ld[et[i]]--; 20 } 21 } 22 int q[maxm],head,tail; 23 int d[maxn]; 24 void spfa(int k){ 25 int now; 26 memset(d,0x7f,sizeof(d)); 27 q[tail++]=k,d[k]=0; 28 while(head<tail){ 29 now=q[head++]; 30 vis[now]=1; 31 for(int i=h[now];i;i=en[i]) 32 if(!ld[et[i]]&&d[now]+1<d[et[i]]){ 33 d[et[i]]=d[now]+1; 34 if(vis[et[i]]){ 35 q[tail++]=et[i]; 36 vis[et[i]]=0; 37 } 38 } 39 } 40 } 41 int main(){ 42 scanf("%d%d",&n,&m); 43 int a,b; 44 for(int i=1;i<=m;i++){ 45 scanf("%d%d",&a,&b); 46 if(a!=b) add(b,a); 47 } 48 scanf("%d%d",&s,&t); 49 dfs1(t); 50 spfa(t); 51 if(d[s]==d[0]) puts("-1"); 52 else printf("%d\n",d[s]); 53 return 0; 54 }