寻找道路

传送门
蒟蒻表示这题只会用BFS。。。
首先把输入的边反过来建,然后跑BFS,看终点可以跑到哪些点。
然后枚举所有点的邻接点,看看是否全部可以跑到终点。
然后把输入的图按照要求重构一遍。跑BFS求答案。。。

#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
const int maxm=210000;
int head[maxm],to[maxm],net[maxm],cnt;
int qhead[maxm],qto[maxm],qnet[maxm],qcnt;
int xhead[maxm],xto[maxm],xnet[maxm],xcnt;
bool flag[maxm],vis[maxm],ok[maxm];
int n,m,s,t;
struct node{
    int x;
    int step;
};
void add(int x,int y)
{
    cnt++;
    to[cnt]=y;
    net[cnt]=head[x];
    head[x]=cnt;
}
void qadd(int x,int y)
{
    qcnt++;
    qto[qcnt]=y;
    qnet[qcnt]=qhead[x];
    qhead[x]=qcnt;
}
void xadd(int x,int y)
{
    xcnt++;
    xto[xcnt]=y;
    xnet[xcnt]=xhead[x];
    xhead[x]=xcnt;
}
void BFS()
{
    flag[t]=1;
    queue <int> dl;
    dl.push(t);
    while(!dl.empty())
    {
        int d=dl.front();
        dl.pop();
        for(int i=xhead[d];i;i=xnet[i])
         if(!flag[xto[i]])
          flag[xto[i]]=1,dl.push(xto[i]);
    }
}
int bfs()
{
    queue <node> dl;
    vis[s]=1;
    dl.push((node){s,0});
    while(!dl.empty())
    {
        node d=dl.front();
        if(d.x==t)
         return d.step;
        dl.pop();
        for(int i=qhead[d.x];i;i=qnet[i])
         if(!vis[qto[i]])
          vis[qto[i]]=1,dl.push((node){qto[i],d.step+1});
    }
    return -1;
}
int main()
{

    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);xadd(y,x);
    }
    scanf("%d%d",&s,&t);
    BFS();
    for(int i=1;i<=n;i++)
    {
      bool f=1;
      for(int j=head[i];j;j=net[j])
       if(!flag[to[j]])
        {
            f=0;
            break;
        }
       ok[i]=f;
    }

    for(int i=1;i<=n;i++)
     for(int j=head[i];j;j=net[j])
       if(ok[to[j]]) 
        qadd(i,to[j]);
    if(flag[s]==0) 
     {
        printf("-1\n");
     }
    else
     printf("%d",bfs());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值