noip2014 提高组题解 road
2014-11-15 15:32
190 查看
题目描述:
寻找道路
( road. cpp/c/pas)
【问题描述】
在有向图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
解题思路:
感觉是一道比较水的题目,首先需要用邻接表存边我就不说了吧(注意需要存正向边和反向边)。
首先从终点T沿着反向边dfs搜索看每个点是否可以到T和每个点的所有孩子是否可以到T
解决了这些问题之后就很简单了,我们发现每条边的长度只有1,那么我们只需要从s出发沿正向边bfs一遍就行了,如果想用spfa我也不拦着你。。。。。。。
代码(由于考场上脑抽,我TM居然用了spfa。。。。。,但是我觉得我的dfs还是很机智的):
寻找道路
( road. cpp/c/pas)
【问题描述】
在有向图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
解题思路:
感觉是一道比较水的题目,首先需要用邻接表存边我就不说了吧(注意需要存正向边和反向边)。
首先从终点T沿着反向边dfs搜索看每个点是否可以到T和每个点的所有孩子是否可以到T
解决了这些问题之后就很简单了,我们发现每条边的长度只有1,那么我们只需要从s出发沿正向边bfs一遍就行了,如果想用spfa我也不拦着你。。。。。。。
代码(由于考场上脑抽,我TM居然用了spfa。。。。。,但是我觉得我的dfs还是很机智的):
//本人是淳朴的C党 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #define MAX(a,b) (a>b?a:b) #define MIN(a,b) (a>b?b:a) struct bian { int num; struct bian *p; }*h[10010]={NULL},*t[10010]={NULL},*fh[10010]={NULL},*ft[10010]={NULL}; int sum[10010]={0}; int hash[10010]={0}; int st,en; int n,m; int f[10010]={0}; int dui[10000010]={0}; int duis=0,duit=0; int k[10010]={0}; void dfs(int k) { int i,j; struct bian *o=NULL; hash[k]=1; for(o=fh[k];o!=NULL;o=o->p) { sum[o->num]--; if(hash[o->num]==1) continue; dfs(o->num); } return; } void spfa() { int i,j; struct bian *o; k[st]=1; duis=1; duit=1; dui[1]=st; f[st]=0; for(;duis<=duit;duis++) { for(o=h[dui[duis]];o!=NULL;o=o->p) { if(hash[o->num]==1 && sum[o->num]==0) { if(f[o->num]==2e9) { f[o->num]=f[dui[duis]]+1; dui[++duit]=o->num; k[o->num]=1; } else if(f[o->num]>f[dui[duis]]+1) { f[o->num]=f[dui[duis]]+1; if(k[o->num]==0) { dui[++duit]=o->num; k[o->num]=1; } } } } k[dui[duis]]=0; } return; } int main() { int i,j,q; freopen("road.in","r",stdin); freopen("road.out","w",stdout); scanf("%d%d",&n,&m); for(i=1;i<=m;i++) { scanf("%d%d",&j,&q); sum[j]++; if(h[j]==NULL) { h[j]=(struct bian *)malloc(sizeof(struct bian)); t[j]=h[j]; } else { t[j]->p=(struct bian *)malloc(sizeof(struct bian)); t[j]=t[j]->p; } t[j]->p=NULL; t[j]->num=q; if(fh[q]==NULL) { fh[q]=(struct bian *)malloc(sizeof(struct bian)); ft[q]=fh[q]; } else { ft[q]->p=(struct bian *)malloc(sizeof(struct bian)); ft[q]=ft[q]->p; } ft[q]->p=NULL; ft[q]->num=j; } scanf("%d%d",&st,&en); dfs(en); for(i=1;i<=n;i++) f[i]=2e9; if(hash[st]==1 && sum[st]==0) spfa(); if(f[en]==2e9) printf("-1"); else printf("%d",f[en]); fclose(stdin); fclose(stdout); return 0; }
相关文章推荐
- 【NOIP2014】提高组
- 2014 Noip提高组 Day2
- 【模拟】洛谷 P1328 NOIP2014提高组 day1 T1 生活大爆炸版石头剪刀布
- NOIP2014提高组考后总结(上)
- [NOIP2014] 提高组 洛谷P1351 联合权值
- NOIP2014 提高组 生活大爆炸版石头剪刀布
- [题解]NOIP2014提高组の题解集合 - by xyz32768
- 【前缀和】【前缀MAX】洛谷 P1351 NOIP2014提高组 day1 T2 联合权值
- NOIP2014提高组考后总结(下)
- 无线网络发射选址 NOIP2014 提高组 Day2 T1
- [NOIP2014] 提高组 洛谷P1941 飞扬的小鸟
- NOIP 提高组 初赛 四、阅读程序写结果 习题集(九)NOIP2014-NOIP2015
- 【NOIP2014提高组】【Day1】【解题报告】
- Noip2014 提高组 Day1 T1 生活大爆炸版石头剪刀布 + Day2 T1 无线网络发射器选址
- NOIP提高组 2014 寻找道路
- NOIP2014提高组DAY1题解
- 解方程 NOIP2014 提高组 Day2 T3
- [NOIP2014] 提高组 洛谷P2038 无线网络发射器选址
- NOIP2014提高组 寻找道路
- ssl 2374 NOIP2014提高组第一天第三题 飞扬的小鸟