寻找道路

来源:互联网 发布:mac是什么意思 编辑:程序博客网 时间:2024/05/01 06:46

传送门
蒟蒻表示这题只会用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());}