1. 程式人生 > >尋找道路

尋找道路

efi -c 這不 esp src pos fig mes algorithm

題目描述

在有向圖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!!

尋找道路