Source and Judge
NOIP2014 提高组 D2T2
Luogu2296
Caioj1567
Problem
【Description】
在有向图 G 中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到 终点的路径,该路径满足以下条件:
1. 路径上的所有点的出边所指向的点都直接或间接与终点连通。
2. 在满足条件 1 的情况下使路径最短。
注意:图 G 中可能存在重边和自环,题目保证终点没有出边。 请你输出符合条件的路径的长度。
【Input】
第一行有两个用一个空格隔开的整数 n 和 m,表示图有 n 个点和 m 条边。
接下来的 m 行每行 2 个整数 x、y,之间用一个空格隔开,表示有一条边从点 x 指向点y。
最后一行有两个用一个空格隔开的整数 s、t,表示起点为 s,终点为 t。
【Output】
输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。
如果这样的路径不存在,输出-1。
【Limited conditions】
对于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。
【Sample input】
6 6
1 2
1 3
2 6
2 5
4 5
3 4
1 5
【Sample output】
3
【Sample explanation】
![](https://cdn.luogu.org/upload/pic/1351.png)
如上图所示,满足条件的路径为1 - >3- >4- >5。注意点2 不能在答案路径中,因为点2连了一条边到点6 ,而点6 不与终点5 连通。
Record
20min
Analysis
sb题
- 建个反向边
- 判断连通性
- 从不连通的地方扫描标记
- spfa
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| #include<cstring> #include<cmath> #include<queue> #include<vector> #include<set> #include<string> #include<queue> #include<iostream> using namespace std; const int MAXN=11000,MAXM=210000; const int INF=0x3f3f3f3f; struct Nod { int hou; bool v,ar; int dis; Nod() { hou=0; v=ar=0; dis=INF; } }p[MAXN]; struct Edge { int y,g; }e[MAXM]; int ln=0; void (int x,int y) { e[++ln]=(Edge){y,p[x].hou};p[x].hou=ln; } void dfs(int x) { p[x].ar=p[x].v=1; for(int k=p[x].hou;k>0;k=e[k].g) { int y=e[k].y; if(!p[y].ar) dfs(y); } } queue<int> lst; bool in[MAXN]; int spfa(int st,int ed) { if(!p[st].v) return -1; lst.push(st);p[st].dis=0;in[st]=1; while(!lst.empty()) { int x=lst.front();lst.pop(); for(int k=p[x].hou;k>0;k=e[k].g) { int y=e[k].y; if(p[y].dis>p[x].dis+1 and p[y].v) { p[y].dis=p[x].dis+1; if(!in[y]) { in[y]=1; lst.push(y); } } } in[x]=0; } return (p[ed].dis==INF)?-1:p[ed].dis; } int main() { int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); ins(y,x); } int st,ed;scanf("%d%d",&st,&ed); dfs(ed); for(int x=1;x<=n;x++) if(!p[x].ar) for(int k=p[x].hou;k>0;k=e[k].g) p[e[k].y].v=0; printf("%d",spfa(ed,st)); }
|