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

P2296 尋找道路

front print empty 空格 sticky while int 排除 nbsp

P2296 尋找道路

題目描述

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

因為有些點是不能用的,所以首先可以搜索出這些點並排除這些點,要所有的點都指向終點且不能在指向其他的,可以在建邊時反向建邊,從終點dfs,找出每個點訪問的次數,在記錄一下他的出度,如果這兩個值相等,則說明指向的只有終點,這個點也就可以用,然後bfs找最短路徑,首先找到的就是最短的,所有的邊權都是1,只需記錄步數即可

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<queue>
 4 using namespace std;
 5 const int MAXN = 10100;
 6 struct Edge{
 7     int to,nxt;
 8 }e[200100];
 9 struct node{
10     int step,x;
11 }cur,nxt;
12 int chu[MAXN],cnt[MAXN],head[MAXN];
13 bool vis[MAXN];
14 int n,m,s,t,tot;
15 queue<node>q;
16 
17 void add(int a,int b)
18 {
19     e[++tot].nxt = head[a];
20     e[tot].to = b;
21     head[a] = tot;
22     chu[b]++;
23 }
24 void dfs(int x)
25 {
26     if (cnt[x]++) return ;
27     for (int i=head[x]; i; i=e[i].nxt)
28         dfs(e[i].to);
29 }
30 void bfs()
31 {
32     cur.x = t,cur.step = 0;
33     q.push(cur);
34     vis[t] = true ;
35     while (!q.empty())
36     {
37         cur = q.front();
38         q.pop();
39         for (int i=head[cur.x]; i; i=e[i].nxt)
40         {
41             int v = e[i].to;
42             if (!vis[v]&&cnt[v]==chu[v])
43             {
44                 if (v==s)
45                 {
46                     printf("%d",cur.step+1);
47                     return ;
48                 }
49                 vis[v] = true;
50                 nxt.x = v; nxt.step = cur.step+1;
51                 q.push(nxt);
52             }
53         }
54     }
55     printf("-1");    
56 }
57 int main()
58 {
59     scanf("%d%d",&n,&m);
60     for (int a,b,i=1; i<=m; ++i)
61     {
62         scanf("%d%d",&a,&b);
63         add(b,a);
64     }
65     scanf("%d%d",&s,&t);
66     dfs(t);
67     bfs();
68     return 0;
69 }

P2296 尋找道路