• P2296 寻找道路


    链接:Miku

    --------------------------------------------

    一道很好的bfs,dfs混合练手题

    --------------------------------------------

    这一道题看第一眼:愚蠢的bfs求最短路,有什么难的!

    然后看见了一堆附加条件:

    1 路径上的所有点的出边所指向的点都直接或间接与终点连通。
    2 在满足条件11的情况下使路径最短
    Ac

    等等,与终点联通?难道我们要把每一个点dfs能不能行吗?

    然而你想一想,如果你能从这个点走到终点,那么倒着走不久走回来了?

    (然而这是有向图额)

    那么就建反图,dfs所有的能到终点的点

    void dfs(int now){
        if(vis[now])
        return ;
        vis[now]=1;
        for(int i=h2[now];i;i=e2[i].ne){
            dfs(e2[i].to);
        }
    }
    dfs

    -------------------------------------------

    预处理结束,重新看一下条件1,好吧,还有一步

    预处理
    for(int i=1;i<=n;++i){
            int f=1;
            for(int j=h1[i];j;j=e1[j].ne){
                if(!vis[e1[j].to]){
                    f=0;
                    break;
                }
            }
            if(!f){
                vis2[i]=1;
            }
        }

    ---------------------------------------------

    处理完这些后,就是个简单的bfs了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 using namespace std;
     5 int vis[10001];
     6 int p;
     7 int p2;
     8 struct b{
     9     int to;
    10     int ne;
    11 }e1[200001],e2[200001];
    12 struct bb{
    13     int p;
    14     int t;
    15 } ;
    16 queue <bb> q;
    17 int vis2[10001];
    18 int n,m;
    19 int x,y;
    20 int dis[10001];
    21 int h1[10001],h2[10001];
    22 int s,t;
    23 void add(int f,int t){
    24     p++;
    25     e1[p].to=t;
    26     e1[p].ne=h1[f];
    27     h1[f]=p;
    28 }
    29 void add2(int f,int t){
    30     p2++;
    31     e2[p2].to=t;
    32     e2[p2].ne=h2[f];
    33     h2[f]=p2;
    34 }
    35 void dfs(int now){
    36     if(vis[now])
    37     return ;
    38     vis[now]=1;
    39     for(int i=h2[now];i;i=e2[i].ne){
    40         dfs(e2[i].to);
    41     }
    42 }
    43 void bfs(int st){
    44     bb now;
    45     now.p=st;
    46     now.t=0;
    47     q.push(now);
    48     while(!q.empty()){
    49         now=q.front();
    50         q.pop();
    51         vis2[now.p]=1;
    52         if(now.p==t){
    53             cout<<now.t;
    54             return ;
    55         }
    56         for(int i=h1[now.p];i;i=e1[i].ne){
    57             int v=e1[i].to;
    58             if(vis[v]&&!vis2[v]){
    59                 bb nn;
    60                 nn.p=v;
    61                 nn.t=now.t+1;
    62                 q.push(nn);
    63             }
    64         }
    65     }
    66     cout<<-1;
    67 }
    68 int main(){
    69     scanf("%d%d",&n,&m);
    70     for(int i=1;i<=m;++i){
    71         scanf("%d%d",&x,&y);
    72         add(x,y);
    73         add2(y,x);
    74     }
    75     scanf("%d%d",&s,&t);
    76     dfs(t);
    77     for(int i=1;i<=n;++i){
    78         int f=1;
    79         for(int j=h1[i];j;j=e1[j].ne){
    80             if(!vis[e1[j].to]){
    81                 f=0;
    82                 break;
    83             }
    84         }
    85         if(!f){
    86             vis2[i]=1;
    87         }
    88     }
    89     bfs(s);    
    90     return 0;
    91 }
    ac
  • 相关阅读:
    opencvsharp BitmapSource图片截取问题
    wpf RenderTargetBitmap保存控件为图片时图片尺寸不对的问题
    c# ??和运算符先后的问题
    wpf 窗口打开后默认设置控件焦点
    win10 requireAdministrator设置开机自启动无效的解决方案
    Gogs webhook钩子 验签 (PHP版本)
    MongoDB管理用户的认证机制
    RocketMQ使用指南及参数详解
    微信公众号h5获取用户openId的方法和步骤
    php中常用的正则表达式函数
  • 原文地址:https://www.cnblogs.com/For-Miku/p/12204101.html
Copyright © 2020-2023  润新知