尋找道路
題目描述
在有向圖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 。
輸入輸出樣例
輸入樣例#1:3 2 1 2 2 1 1 3輸出樣例#1:
-1輸入樣例#2:
6 6 1 2 1 3 2 6 2 5 4 5 3 4 1 5輸出樣例#2:
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。
解題思路:
一開始的大致思路是對的,反向建圖,從T開始找到能夠到達的點,在刪掉不合法的點,再次bfs
出現問題:
1.不夠仔細,i打成j
2.第二次bfs的時候,從S出發會出現環的情況以及無法到達T的情況,這不好處理。
所以第二次bfs從T出發可以避免這個問題。
3.沒有耐心。一定要仔細分析透之後在動手。
因為是反向建的邊,那麽如果T不能到達點i,那麽與i相連的點就是不合法的點,要刪掉(不滿足“路徑上的所有點的出邊所指向的點都直接或間接與終點連通”)。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<vector> #include<queue> #define ll long long #define inf 214845000 using namespace std; inline int read() { int x=0,w=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘) w=-1;ch=getchar();} while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar(); return x*w; } const int N=200010; struct node{ int u,v,ne; }e[N]; int h[N],tot; void add(int u,int v) { tot++;e[tot]=(node){u,v,h[u]};h[u]=tot; } int n,m,S,T,d[N]; bool fg1[N],fg2[N]; queue<int>q; void BFS() { q.push(T); while(!q.empty()) { int ff=q.front();q.pop();fg1[ff]=1; for(int i=h[ff];i;i=e[i].ne) { int rr=e[i].v; if(fg1[rr]==0)q.push(rr); } } for(int i=1;i<=n;++i) if(fg1[i]==0) { for(int j=h[i];j;j=e[j].ne) { int rr=e[j].v;fg2[rr]=1; } } } void bfs() { for(int i=1;i<=n;++i) d[i]=inf; d[T]=0;q.push(T); while(!q.empty()) { int ff=q.front();q.pop(); for(int i=h[ff];i;i=e[i].ne) { int rr=e[i].v; if(fg2[rr]==0 && d[rr]>d[ff]+1) { d[rr]=d[ff]+1; q.push(rr); } } } } int main() { n=read();m=read(); for(int i=1;i<=m;++i) { int x,y;x=read();y=read(); add(y,x); } S=read();T=read(); BFS();bfs(); if(d[S]==inf) cout<<"-1"; else cout<<d[S]; return 0; }
天上,真的會有花兒盛開嗎?
fighting!!
尋找道路