1 solutions
-
0
树的遍历,预处理可以走到终点的所有点
然后枚举所有点,判断是否当前点的所有出边都能够走到终点,如果可以这样的点为合法点
然后从起点到终点,根据合法点做一遍bfs
#include<bits/stdc++.h> using namespace std; const int N=10010,M=400010; int n,m; int h[N],e[M],ne[M],idx; int dist[N]; bool st[N],valid[N]; //st[i]=1 表示可以从i走到终点,valid[i]=1,表示i的所有出边都可以走到终点 void add(int a,int b) { e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(int u) { st[u]=true; for(int i=h[u];i!=-1;i=ne[i]) { if(i%2==0) continue;//跳过正向边 int j=e[i]; if(!st[j]) { dfs(j); } } } int bfs(int start,int target) { if(!valid[start]) return -1;//起点不合法 memset(dist,0x3f,sizeof dist); queue<int> q; q.push(start); dist[start]=0; while(q.size()) { int t=q.front(); q.pop(); for(int i=h[t];i!=-1;i=ne[i]) { if(i%2) continue;//跳过反向边 int j=e[i]; if(!valid[j]) continue;//跳过不合法的点 if(dist[j]>dist[t]+1) { dist [j]=dist[t]+1; q.push(j); } } } if(dist[target]==0x3f3f3f3f) return -1; return dist[target]; } int main() { cin>>n>>m; memset(h,-1,sizeof h); while(m--) { int a,b; cin>>a>>b; add(a,b); add(b,a); } int s,t; cin>>s>>t; dfs(t); //找到所有可以走到t的点 for(int i=1;i<=n;i++) { valid[i]=true; for(int j=h[i];j!=-1;j=ne[j]) { if(j%2==0&&!st[e[j]]) //至少有一条出边不能走到终点 { valid[i]=false; break; } } } cout<<bfs(s,t); return 0; }
- 1
Information
- ID
- 1110
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 10
- Tags
- # Submissions
- 1
- Accepted
- 1
- Uploaded By