首页 > 代码库 > 洛谷 P2296 寻找道路(NOIp2014D2T2)
洛谷 P2296 寻找道路(NOIp2014D2T2)
题目描述
在有向图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 。
输入输出样例
3 2 1 2 2 1 1 3
-1
6 6 1 2 1 3 2 6 2 5 4 5 3 4 1 5
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。
【分析】
是一看思路就很清晰的题,先正向建图,再反向建图后dfs判断点能不能用,最后bfs跑一遍最短路。
注意这里每条边长度都一样,已经出队的点再进队没有意义。
【代码】
1 #include <bits/stdc++.h> 2 #define inf 0x7fffffff 3 using namespace std; 4 5 map<pair<int, int>, int> ma; 6 pair<int, int> pa; 7 8 struct node { 9 int next, to; 10 }e[200005], ee[2000005]; 11 12 struct State { 13 int x, t; 14 }; 15 16 int n, m, x[200005], y[200005], s, t, dis[10005], ans; 17 int cnt, head[200005], ccnt, hea[200005]; 18 bool vis[10005], v[10005], vv[10005]; 19 20 void add1(int u, int v) { 21 e[++cnt].to=v, e[cnt].next=head[u], head[u]=cnt; 22 } 23 void add2(int u, int v) { 24 ee[++ccnt].to=v, ee[ccnt].next=hea[u], hea[u]=ccnt; 25 } 26 27 void dfs(int s) { 28 vis[s]=true; 29 for (int i=hea[s];i;i=ee[i].next) { 30 if (vis[ee[i].to]) 31 continue; 32 else { 33 vis[ee[i].to]=true; 34 dfs(ee[i].to); 35 } 36 } 37 } 38 39 void bfs() { 40 queue<State> Q; 41 State init; 42 init.x=s, init.t=0; 43 Q.push(init); 44 v[s]=true; 45 while (!Q.empty()) { 46 State now=Q.front(); 47 Q.pop(); 48 if (now.x==t) { 49 ans=now.t; 50 break; 51 } 52 for (int i=head[now.x];i;i=e[i].next) { 53 if (vv[e[i].to] && !v[e[i].to]) { 54 State nnow=now; 55 nnow.x=e[i].to, nnow.t++; 56 Q.push(nnow); 57 v[nnow.x]=true; 58 } 59 } 60 } 61 } 62 63 int main() { 64 cin >> n >> m; 65 for (int i=1;i<=m;++i) { 66 scanf("%d%d", &x[i], &y[i]); 67 pa=make_pair(x[i], y[i]); 68 if (ma[pa]) { 69 x[i]=y[i]=0; 70 continue; 71 } 72 ma[pa]=1; 73 } 74 cin >> s >> t; 75 if (s==t) 76 return 0; 77 for (int i=1;i<=m;++i) { 78 if (x[i] && y[i]){ 79 add1(x[i], y[i]); 80 add2(y[i], x[i]); 81 } 82 } 83 dfs(t); 84 for (int i=1;i<=n;++i) 85 if (i==t) 86 vv[i]=true; 87 else if (vis[i]) { 88 bool flag=true; 89 for (int j=head[i];j;j=e[j].next) { 90 if (!vis[e[j].to]) { 91 flag=false; 92 continue; 93 } 94 } 95 vv[i]=flag; 96 } 97 bfs(); 98 if (ans) 99 cout << ans << endl; 100 else 101 cout << -1 << endl; 102 }
洛谷 P2296 寻找道路(NOIp2014D2T2)