1. 程式人生 > >【NOIP2014提高組】尋找道路

【NOIP2014提高組】尋找道路

題目背景

NOIP2014 提高組 Day2 試題。

題目描述

在有向圖 G 中,每條邊的長度均為 1,現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件:  1.路徑上的所有點的出邊所指向的點都直接或間接與終點連通。  2.在滿足條件 1 的情況下使路徑最短。  注意:圖 G 中可能存在重邊和自環,題目保證終點沒有出邊。  請你輸出符合條件的路徑的長度。

輸入格式

第一行有兩個用一個空格隔開的整數 n 和 m,表示圖有 n 個點和 m 條邊。  接下來的 m 行每行 2 個整數 x、y,之間用一個空格隔開,表示有一條邊從點 x 指向點y。  最後一行有兩個用一個空格隔開的整數 s、t,表示起點為 s,終點為 t。

輸出格式

輸出只有一行,包含一個整數,表示滿足題目描述的最短路徑的長度。如果這樣的路徑不存在,輸出 -1。

樣例資料 1

輸入

3 2  1 2  2 1  1 3

輸出

-1

樣例資料 2

輸入

6 6  1 2  1 3  2 6  2 5  4 5  3 4  1 5

輸出

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。

解析:

       題解是BFS,而我用的是另一種方法。

       如果沒有限制一,那麼就是一道最短路的板題,其實對於限制一,我們只需要將與出度為0且不是終點的點相連的點標記不能走,然後直接最短路,就可以了。為什麼是對的?稍微畫圖想想你就明白了。

程式碼:

#include <bits/stdc++.h>
using namespace std;

const int Maxn=10005;
const int Maxm=200005;
const int inf=1e9;
int n,m,size,s,t;
int first[Maxn],First[Maxn],v[Maxn],pre[Maxn],dis[Maxn],to[Maxn],vis[Maxn];
struct shu{int to,next;};
shu edge[Maxm<<1],Edge[Maxm<<1];

inline int get_int()
{
	int x=0,f=1;
	char c;
	for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
	if(c=='-') f=-1,c=getchar();
	for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
	return x*f;
}

inline void build(int x,int y)
{
	edge[++size].next=first[x];
	first[x]=size;
	edge[size].to=y;
	Edge[size].next=First[y];
	First[y]=size;
	Edge[size].to=x;
}

inline void dfs(int point)
{
	for(int u=First[point];u;u=Edge[u].next)
	{
	  int to=Edge[u].to;
	  first[to]=0;
	}
}

inline void dijkstra()
{
	priority_queue<pair<int,int> >q;
	for(int i=1;i<=n;i++) dis[i]=inf;
	dis[s]=0,q.push(make_pair(0,s));
	while(q.size())
	{
	  int point=q.top().second;
	  q.pop();if(vis[point]) continue;vis[point]=1;
	  for(int u=first[point];u;u=edge[u].next)
	  {
	  	int to=edge[u].to;
	  	if(dis[to] > dis[point] + 1)
	  	{
	  	  dis[to]=dis[point]+1;
	  	  q.push(make_pair(-dis[to],to));
	  	}
	  }
	}
}

int main()
{
	n=get_int(),m=get_int();
	for(int i=1;i<=m;i++)
	{
	  int x=get_int(),y=get_int();
	  build(x,y),to[x]++;
	}
	s=get_int(),t=get_int();
	for(int i=1;i<=n;i++) if(!to[i] && i!=t) dfs(i);
	dijkstra();
	if(dis[t]==inf) cout<<"-1\n";
	else cout<<dis[t]<<"\n";
	return 0;
}