CODEVS 3731寻找道路 (重修版)
来源:互联网 发布:excel表格数据素材 编辑:程序博客网 时间:2024/04/28 21:18
题目描述 Description
在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:
1.路径上的所有点的出边所指向的点都直接或间接与终点连通。
2.在满足条件1的情况下使路径最短。
注意:图G中可能存在重边和自环,题目保证终点没有出边。
请你输出符合条件的路径的长度。
输入描述 Input Description
第一行有两个用一个空格隔开的整数n和m,表示图有n个点和m条边。
接下来的m行每行2个整数x、y,之间用一个空格隔开,表示有一条边从点x指向点y。
最后一行有两个用一个空格隔开的整数s、t,表示起点为s,终点为t。
路径上的所有点的出边所指向的点都直接或间接与终点连通。
输出描述 Output Description
输出文件名为road.out。
输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出-1。
路径上的所有点的出边所指向的点都直接或间接与终点连通。
对于这句话,我们该如何处理呢?
先反向建边,从终点跑一边SPFA,记录每个点能不能被终点跑到。
然后,我们需要对这些跑不到的点进行处理,跑反向图,从这些点只进行一层BFS,把他们连接的点都标为不可走。
从起点再跑SPFA,遇到不能走的点就continue掉。
#include<cstdio>#include<queue>using namespace std;const int inf=0x7ffffff;const int maxn=400000+500;int n,m;struct Edge{ int f; int to; int d; int next;}edge1[maxn],edge[maxn];int head[maxn],head1[maxn];bool vis[maxn],alive[maxn];bool kd[maxn];int dist[maxn];int ss,tt;int tot;void add(int f,int t,int d){ edge[++tot]=(Edge){f,t,d,head[f]}; head[f]=tot; }int tot1;void add1(int f,int t,int d){ edge1[++tot1]=(Edge){f,t,d,head1[f]}; head1[f]=tot1; }queue<int>q1;void spfa(){ alive[tt]=1; q1.push(tt); while(!q1.empty()) { int x=q1.front(); q1.pop(); for(int i=head1[x];i;i=edge1[i].next) { Edge e=edge1[i]; if(!vis[e.to]) { vis[e.to]=1; alive[e.to]=1; kd[e.to]=1; q1.push(e.to); } } }}void kill(int x){ for(int i=head1[x];i;i=edge1[i].next) { Edge e=edge1[i]; if(e.to==ss) continue; if(alive[e.to]) alive[e.to]=0; }}queue<int>q;void spfa1(){ for(int i=1;i<=n;i++) dist[i]=inf,vis[i]=0; dist[ss]=0; q.push(ss); while(!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i;i=edge[i].next) { Edge e=edge[i]; if(alive[e.to]) { if(dist[e.to]>dist[x]+e.d) { dist[e.to]=dist[x]+e.d; if(!vis[e.to]) { vis[e.to]=1; q.push(e.to); } } } } }}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b,1); add1(b,a,1); } scanf("%d%d",&ss,&tt); spfa(); for(int i=1;i<=n;i++) { if(!alive[i]&&!kd[i]) kill(i); } spfa1(); if(dist[tt]!=inf) printf("%d\n",dist[tt]); else puts("-1"); return 0;}
0 0
- CODEVS 3731寻找道路 (重修版)
- CODEVS 3731 寻找道路
- codevs 3731 寻找道路
- codevs 3731 寻找道路
- 寻找道路(codevs 3731)题解
- codevs 寻找道路
- 【Codevs】3731 寻找道路 --2014年NOIP全国联赛提高组
- Codevs 3731 寻找道路 2014年 NOIP全国联赛提高组
- 3731 寻找道路
- 寻找道路
- 寻找道路
- 寻找道路
- 寻找不同的道路
- Noip2014寻找道路题解
- NOIP2014 寻找道路
- [NOIP2014]寻找道路
- Vijos1909 寻找道路
- NOIP2014寻找道路
- Oracle:查看对象有没有被其他对象引用语句
- UnicodeDecodeError: 'gbk' codec can't decode byte 0xaf in position 683: illegal multibyte sequence
- px,dp,sp的简单理解
- swift 监听网络状态
- 支付宝 iOS SDK 官方下载页面
- CODEVS 3731寻找道路 (重修版)
- nmap#4有趣功能
- 文章标题
- dede获取上级栏目名称
- Android初学习 - 转载一篇Handler机制总结
- 关于ACM练习第八题的思考和解答
- mt7620 按键驱动
- 基于比较的内部排序总结
- uboot 下载内核和文件系统的步骤