洛谷P2296 寻找道路(NOIp2014)

来源:互联网 发布:淘宝账号怎么绑定手机 编辑:程序博客网 时间:2024/05/22 00:30

BFS

题目传送门

一开始就想到正解,然而读优打错T了五发。。。

首先建一个反图。然后从终点开始BFS。对于遍历到的点,遍历它的所有出边,如果有一个不可到,那么也把它标记为不可到(正着)。然后正着跑一遍BFS计算距离。

注意更新标记的时候需要另开一个数组,否则会影响后面的节点。

代码:

#include<cstdio>#include<cstring>#include<algorithm>#define MAXN 10000#define MAXM 200000using namespace std;struct edge{    int next,to;};int n,m,k,ans;int h1[MAXN+5],h2[MAXN+5],que[MAXN+5][2];bool f1[MAXN+5],f2[MAXN+5];edge ed[MAXM*2+5];inline char readc(){//读优    static char buf[100000],*l=buf,*r=buf;    if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);    if (l==r) return EOF; return *l++;}inline int _read(){    int num=0; char ch=readc();    while (ch<'0'||ch>'9') ch=readc();    while (ch>='0'&&ch<='9'){ num=num*10+ch-48; ch=readc(); }    return num;}void addedge(int x,int y,int *h){    ed[++k].next=h[x]; ed[k].to=y; h[x]=k;}void bfs1(int s){//第一遍BFS    int r=0,w=1; que[1][0]=s; f1[s]=true;    while (r<w){        int x=que[++r][0];        for (int i=h2[x];i;i=ed[i].next)            if (!f1[ed[i].to]){                que[++w][0]=ed[i].to;                f1[ed[i].to]=true;            }    }}void bfs2(int s,int t){//第二遍BFS    int r=0,w=1; que[1][0]=s; que[1][1]=0; f2[s]=true;    while (r<w){        int x=que[++r][0];        if (x==t){            ans=que[r][1];            return;        }        for (int i=h1[x];i;i=ed[i].next)            if (f1[ed[i].to]&&!f2[ed[i].to]){                que[++w][0]=ed[i].to;                que[w][1]=que[r][1]+1;                f2[ed[i].to]=true;            }    }    ans=-1;}int main(){    n=_read(); m=_read();    for (int i=1;i<=m;i++){        int u=_read(),v=_read();        addedge(v,u,h2); addedge(u,v,h1);    }    int s=_read(),t=_read();    bfs1(t);    for (int i=1;i<=n;i++)//遍历完后更新标记        if (f1[i])            for (int j=h1[i];j;j=ed[j].next)                if (!f1[ed[j].to]){//有一个                    f2[i]=true;                    break;                }    for (int i=1;i<=n;i++)        if (f2[i])            f1[i]=false;    memset(f2,false,sizeof(f2));    bfs2(s,t);    printf("%d\n",ans);    return 0;}
原创粉丝点击