博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
1807. [NOIP2014]寻找道路P2296 寻找道路
阅读量:7287 次
发布时间:2019-06-30

本文共 3066 字,大约阅读时间需要 10 分钟。

题目描述

在有向图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。

 

这道题我们可以用逆向思维来想

如果一个点能到达终点,那么终点也一定能到达这个点

这样就简单了

从终点跑一遍BFS,算出每一个点的访问次数

然后把不能走的点删去

最后spfa带走

一个很有意思的能够找出访问次数而且不会死循环的方法

1 int to=edge[i].v;

2 if(cs[to]++)continue;
3 q.push(to); 
 
完整代码
1 #include
2 #include
3 #include
4 #include
5 #include
6 #define INF 0x7ffffff 7 using namespace std; 8 int read(int & n) 9 { 10 int flag=0,x=0;char c='/'; 11 while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} 12 while(c>='0'&&c<='9')x=x*10+(c-48),c=getchar(); 13 if(flag)n=-x;else n=x; 14 } 15 const int MAXN=200001; 16 int n,m,bgx,bgy; 17 int rudu[MAXN]; 18 struct node 19 { 20 int u,v,w,nxt; 21 }edge[MAXN]; 22 int num=1; 23 int head[MAXN]; 24 int flag[MAXN];// 记录每个值是否能够到达终点 25 int cs[MAXN]; 26 int dis[MAXN]; 27 int vis[MAXN]; 28 void add_edge(int ll,int rr,int ww) 29 { 30 edge[num].u=ll; 31 edge[num].v=rr; 32 edge[num].w=ww; 33 edge[num].nxt=head[ll]; 34 head[ll]=num++; 35 } 36 void bfs() 37 { 38 queue
q; 39 int tot=0; 40 q.push(bgx),tot++; 41 while(q.size()!=0) 42 { 43 int p=q.front(); 44 q.pop(); 45 for(int i=head[p];i!=-1;i=edge[i].nxt) 46 { 47 int to=edge[i].v; 48 if(cs[to]++)continue; 49 q.push(to); 50 } 51 } 52 //rudu[bgy]=0; 53 for(int i=1;i<=n;i++) 54 if(rudu[i]!=cs[i]&&i!=bgy) 55 flag[i]=1; 56 } 57 void dele() 58 { 59 for(int i=1;i<=num;i++) 60 { 61 if(flag[edge[i].u]!=0) 62 { 63 edge[i].u=-1; 64 edge[i].v=-1; 65 edge[i].w=-1; 66 edge[i].nxt=-1; 67 } 68 } 69 } 70 void spfa() 71 { 72 queue
q; 73 q.push(bgx); 74 dis[bgx]=0; 75 while(q.size()!=0) 76 { 77 int p=q.front(); 78 q.pop(); 79 vis[p]=0; 80 for(int i=head[p];i!=-1;i=edge[i].nxt) 81 { 82 if(edge[i].u==-1)continue; 83 int to=edge[i].v; 84 if(dis[to]>dis[p]+edge[i].w) 85 { 86 dis[to]=dis[p]+edge[i].w; 87 if(vis[to]==0) 88 { 89 vis[to]=1; 90 q.push(to); 91 } 92 } 93 } 94 } 95 if(dis[bgy]==INF) 96 printf("-1"); 97 else 98 printf("%d",dis[bgy]); 99 }100 int main()101 {102 freopen("roadb.in","r",stdin);103 freopen("roadb.out","w",stdout);104 read(n);read(m);105 for(int i=1;i<=n;i++)head[i]=-1,dis[i]=INF;106 for(int i=1;i<=m;i++)107 {108 int x,y;109 read(x);read(y);110 add_edge(y,x,1);111 rudu[x]++;112 }113 read(bgy);read(bgx);114 bfs();115 dele();116 spfa();117 return 0;118 }

 

 

转载地址:http://aqdjm.baihongyu.com/

你可能感兴趣的文章
Android进阶:十四、熟悉Android打包编译的流程
查看>>
北漂五年,逐渐理解了为什么我一定要来大城市
查看>>
进击RDC的第二天(3.22)
查看>>
数据预取小轮子
查看>>
《图解HTTP》第7章_确保Web安全的HTTPS-思维导图
查看>>
Netty实现自定义通信协议
查看>>
人人都能学会的python编程教程7:元祖(tuple)
查看>>
如果AI能够测试软件修复bug,程序员会更轻松吗
查看>>
深入理解计算机系统(二)
查看>>
小程序生成二维码图片保存相册并分享到朋友圈
查看>>
java基础:设计模式-学习笔记
查看>>
Glide 使用必须知道的基础属性——Google推荐的图片加载库
查看>>
关于Jdk中的静态代理跟动态代理
查看>>
css_06 | CSS——CSS 给文本加样式:② 文本属性
查看>>
关于HTTP的Oauth,Session和Cookie, Proxy概念
查看>>
浅谈ThreadLocal(线程本地变量)
查看>>
漫画行业有妖气:曾经的一哥,今日的难兄
查看>>
java springboot b2b2c shop 多用户商城系统源码:服务容错保护(Hystrix服务降级)
查看>>
Java springboot B2B2C o2o多用户商城 springcloud架构使用Spring Security安全控制
查看>>
java B2B2C springmvc mybatis电子商城系统-Spring Cloud 服务消费(Ribbon)
查看>>