Noip2014 尋找道路————最短路+搜索

題解:本題主要考查最短路+搜索
簡要題意:一個有向圖邊都爲1,給定起點和終點,找一條從起點到終點的最短路徑。
1.搜索:本題會有不與終點相連的點,就要刪除它們,以及與他們連一條邊的點,就在圖上遍歷標記。(注意:不能直接消去第一次打上的標記,第二次刪除標記時是可能有後效性的)
2.最短路:跳過沒有標記的點跑一邊最短路即可
代碼如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
struct E
{
	int start,to;
}e[389574];
int d[389574],h[982341];
bool v[346237],flag[923245];
int n,m,p,x,y,a,b,P=0;
void add(int start,int to)
{
	e[++P].start=h[start];
	e[P].to=to;
	h[start]=P;
}
void spfa(int p)
{
	memset(v,0,sizeof(v));
	memset(d,9999999,sizeof(d));
	queue<int> q;
	q.push(p);
	v[p]=1;d[p]=0;
	while(!q.empty())
	{
		int k=q.front();
		q.pop();v[k]=0;
		for(int i=h[k];i;i=e[i].start)
		{
			int t=e[i].to;
			if(d[t]>d[k]+1&&flag[t])
			{
				d[t]=d[k]+1;
				if(!v[t]){v[t]=1;q.push(t);}
			}
		}
	}
}
void bfs(int p)
{
	queue<int> q;
	memset(v,0,sizeof(v));
	q.push(p);
	flag[p]=v[p]=1;
	while(!q.empty())
	{
		int k=q.front();q.pop();
		for(int i=h[k];i;i=e[i].start)
		{
			int t=e[i].to;
			if(!v[t])
			{
				v[t]=flag[t]=1;
				q.push(t);
			}
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y;
		add(y,x);
	}
	cin>>a>>b;
	bfs(b);
	for(int i=1;i<=n;i++)v[i]=flag[i];
	for(int i=1;i<=n;i++)
	{
		if(!v[i])
			for(int j=h[i];j;j=e[j].start)
			{
				int k=e[j].to;
				if(flag[k])flag[k]=0;
			}
	}
	spfa(b);
	if(d[a]<=999999)cout<<d[a]<<endl;
	else cout<<"-1"<<endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章