在有向圖 中,每條邊的長度均爲 ,現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑知足如下條件:html
- 路徑上的全部點的出邊所指向的點都直接或間接與終點連通。
- 在知足條件 的狀況下使路徑最短。
注意:圖 GG 中可能存在重邊和自環,題目保證終點沒有出邊。node
請你輸出符合條件的路徑的長度。c++
這道題,咱們考慮哪些點可以到達終點,問題等價於:反向建邊後,終點能到達哪些點。git
void dfs(int x){ h[x]=true; for(auto i:E[x]) if(!h[i])dfs(i); }
正是反向建邊後的邊集。web
就表示 號點能到終點。app
因此,咱們能夠判斷哪些點能夠走了。svg
能通過的點要知足 個條件:spa
for(int i=1;i<=n;i++) if(h[i]){ dis[i]=true; for(auto j:v[i]) if(!h[j]){dis[i]=false;break;} }
這部作完了,就能夠開始 了。code
邊權全都是 天然是第 次搜到的就是最優解。xml
q.push((node){s,0}); while(q.size()){ node x=q.front(); if(x.x==t){ cout<<x.s; return 0; } for(auto i:v[x.x]) if(dis[i]&&!vis[i]){ vis[i]=true; q.push((node){i,x.s+1}); } q.pop(); }cout<<-1;
仍是很簡單的。
總代碼:
#include <bits/stdc++.h> using namespace std; typedef long long ll; template<typename T>inline void read(T &FF){ T RR=1;FF=0;char CH=getchar(); for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1; for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48); FF*=RR; } struct node{ int x,s; }; bool h[10010],vis[10010]; int n,m,dis[10010],s,t; vector<int>v[10010]; vector<int>E[10010]; queue<node>q; void dfs(int x){ h[x]=true; for(auto i:E[x]) if(!h[i])dfs(i); } int main(){ read(n);read(m); for(int i=1;i<=m;i++){ int x,y;read(x);read(y); v[x].push_back(y); E[y].push_back(x); } read(s);read(t); dfs(t); for(int i=1;i<=n;i++) if(h[i]){ dis[i]=true; for(auto j:v[i]) if(!h[j]){dis[i]=false;break;} } q.push((node){s,0}); while(q.size()){ node x=q.front(); if(x.x==t){ cout<<x.s; return 0; } for(auto i:v[x.x]) if(dis[i]&&!vis[i]){ vis[i]=true; q.push((node){i,x.s+1}); } q.pop(); }cout<<-1; return 0; }