题目
题解
条件1可以建反向图。从终点走,走到最后如果入度为0,就说明这个点可以出现在答案队列中,打上标记
然后给有标记的图跑一边最短路(正向反向随意,建议反向,因为读入的时候就可以直接读反向)
Code
#include<cstdio>
#define inf 1e9+7
using namespace std;
struct node
{
int head,next,to;
}a[200005];
int n,m,x,y,h,t,st,en,tot,num[10005],dis[10005],d[500005];
bool b[10005],bj[10005],bz[10005],flag[200005];
void add(int x,int y)
{
a[++tot].to=y;
a[tot].next=a[x].head;
a[x].head=tot;
}
void dij()
{
int dis_mn,x;
for (int i=1;i<=n;++i)
dis[i]=inf;
dis[en]=0;
while (true)
{
dis_mn=inf;
for (int i=1;i<=n;++i)
{
if (bj[i]&&!bz[i]&&dis[i]<dis_mn)
{
dis_mn=dis[i];
x=i;
}
}
if (dis_mn==inf) break;
bz[x]=true;
for (int i=a[x].head;i;i=a[i].next)
{
int v=a[i].to;
if (bj[v]&&!bz[v]&&dis[v]>dis[x]+1) dis[v]=dis[x]+1;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;++i)
{
scanf("%d%d",&x,&y);
++num[x];
add(y,x);
}
scanf("%d%d",&st,&en);
h=0;t=1;
d[1]=en;
b[en]=true;
while (h<t)
{
++h;
int u=d[h];
for (int i=a[u].head;i;i=a[i].next)
{
int v=a[i].to;
if (!flag[i])
{
d[++t]=v;
--num[v];
b[v]=true;
flag[i]=true;
}
}
}
for (int i=1;i<=n;++i)
if (num[i]<=0&&b[i]) bj[i]=true;
dij();
if (dis[st]==inf) printf("-1\n");
else printf("%d\n",dis[st]);
return 0;
}