zoukankan      html  css  js  c++  java
  • 洛谷 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 }
  • 相关阅读:
    1093 Count PAT's(25 分)
    1089 Insert or Merge(25 分)
    1088 Rational Arithmetic(20 分)
    1081 Rational Sum(20 分)
    1069 The Black Hole of Numbers(20 分)
    1059 Prime Factors(25 分)
    1050 String Subtraction (20)
    根据生日计算员工年龄
    动态获取当前日期和时间
    对计数结果进行4舍5入
  • 原文地址:https://www.cnblogs.com/qqq1112/p/11536145.html
Copyright © 2011-2022 走看看