• 洛谷 P2296 【寻找道路】



    思路 :首先既然要满足第一个条件,我们可以建反向边,从起点出发走反向边,标记所能到达的点。没有被标记过的点就把他的父亲(谁到它的点)和它本身给标记为不可到达,然后就求最短路,如果碰到标记为不可到达的点,就continue,最后dis[e]就是答案。

    代码 :

     1 #include <bits/stdc++.h>
     2 #define INF 0x3f3f3f3f
     3 using namespace std;
     4 int n, m, head[10001], head1[10001], dis[10001], vis[10001], no[10001], mark[10001], num, num1, s, e;
     5 struct node
     6 {
     7     int next, to, val;
     8 }stu[200001], stu1[200001];
     9 inline void add(int x, int y, int z)//正向边 
    10 {
    11     stu[++num].next = head[x];
    12     stu[num].to = y;
    13     stu[num].val = z;
    14     head[x] = num;
    15     return;
    16 }
    17 inline void add1(int x, int y, int z)//反向边 
    18 {
    19     stu1[++num1].next = head1[x];
    20     stu1[num1].to = y;
    21     stu1[num1].val = z;
    22     head1[x] = num1;
    23     return;
    24 }
    25 inline void dfs(int u)//从终点dfs搜索能到达的点 
    26 {
    27     for(register int i = head1[u]; i; i = stu1[i].next)
    28     {
    29         int k = stu1[i].to;
    30         if(!mark[k])
    31         {
    32             mark[k] = 1;
    33             dfs(k);
    34         }
    35     }
    36     return;
    37 }
    38 inline void spfa(int s)//求最短路 
    39 {
    40     queue < int > pru;
    41     memset(vis, 0, sizeof(vis));
    42     memset(dis, INF, sizeof(dis));
    43     dis[s] = 0;
    44     vis[s] = 1;
    45     pru.push(s);
    46     while(!pru.empty())
    47     {
    48         int u = pru.front();
    49         pru.pop();
    50         vis[u] = 0;
    51         for(register int i = head[u]; i; i = stu[i].next)
    52         {
    53             int k = stu[i].to;
    54             if(no[k])//如果不可以走(不满足条件1) 
    55             {
    56                 continue;
    57             }
    58             if(dis[k] > dis[u] + stu[i].val)
    59             {
    60                 dis[k] = dis[u] + stu[i].val;
    61                 if(!vis[k])
    62                 {
    63                     vis[k] = 1;
    64                     pru.push(k);
    65                 }
    66             }
    67         }
    68     }
    69     return;
    70 }
    71 signed main()
    72 {
    73     scanf("%d %d", &n, &m);
    74     for(register int i = 1, x, y; i <= m; ++i)
    75     {
    76         scanf("%d %d", &x, &y);
    77         add(x, y, 1);
    78         add1(y, x, 1);
    79     }
    80     scanf("%d %d", &s, &e);
    81     dfs(e);
    82     mark[e] = 1;//记得把终点标记为搜到了 
    83     for(register int u = 1; u <= n; ++u)//搜索所有点 
    84     {
    85         if(!mark[u])//没被标记的 
    86         {
    87             no[u] = 1;//不能走 
    88             for(register int i = head1[u]; i; i = stu1[i].next)//他的父亲也不能走 
    89             {
    90                 int k = stu1[i].to;
    91                 no[k] = 1;
    92             }
    93         }
    94     }
    95     spfa(s);
    96     printf(dis[e] == INF ? "-1" : "%d", dis[e]);
    97     return 0;
    98 }
  • 相关阅读:
    通信信号处理的一些基本常识
    欧拉公式
    css3圆角讲解
    css3投影讲解、投影
    css3变形讲解
    浏览器兼容问题
    css3渐变详解
    css中em与px
    복 경 에 갑 니 다 去北京
    我在北京:)
  • 原文地址:https://www.cnblogs.com/qqq1112/p/11536145.html
Copyright © 2020-2023  润新知