題解:本題主要考查最短路+搜索
簡要題意:一個有向圖邊都爲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;
}