zoukankan      html  css  js  c++  java
  • NOIP TG 2014 寻找道路 【SPFA】

    题目描述

    在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:

    1 .路径上的所有点的出边所指向的点都直接或间接与终点连通。

    2 .在满足条件1 的情况下使路径最短。

    注意:图G 中可能存在重边和自环,题目保证终点没有出边。

    请你输出符合条件的路径的长度。

    输入输出格式

    输入格式:

    输入文件名为road .in。

    第一行有两个用一个空格隔开的整数n 和m ,表示图有n 个点和m 条边。

    接下来的m 行每行2 个整数x 、y ,之间用一个空格隔开,表示有一条边从点x 指向点y 。

    最后一行有两个用一个空格隔开的整数s 、t ,表示起点为s ,终点为t 。

    输出格式:

    输出文件名为road .out 。

    输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。如果这样的路径不存在,输出- 1 。

    输入输出样例

    输入样例#1:
    3 2
    1 2
    2 1
    1 3
    输出样例#1:
    -1
    输入样例#2:
    6 6
    1 2
    1 3
    2 6
    2 5
    4 5
    3 4
    1 5
    输出样例#2:
    3 

    说明

    对于30%的数据,0<n≤10,0<m≤20;

    对于60%的数据,0<n≤100,0<m≤2000;

    对于100%的数据,0<n≤10,000,0<m≤200,000,0<x,y,s,t≤n,x≠t。

    分析

    【瞎扯】

    题目都没看仔细就把这题当成最短路模板做了,一边做还一边想,这种模板题居然还【普及+/提高-】,还被老师拿出来给我们做。

    写完发现样例过不了,然后一看样例解释的图片就懵了。这个样例有问题啊喂,最短路明明是2,怎么会是3?然后接着往下看就更懵了,

    注意:点2不能在答案路径中,因为点2连了一条边到点6,而点6不与终点5连通。

    这啥玩意儿,我怎么不知道还有这个规则,然后回过头去看题目的条件1。好吧我没看见。【服了!】


    【正经】

    扯完了,来说这个条件1究竟改怎么对付。我们要找到那些不符合条件1的点,也就是在其出边中至少有一条不能到达终点。怎么解决呢?

    建立反图。从终点开始往回跑BFS,不能搜到的点及与其直接相连的点就是不符合条件1的点。样例2中,点6不能被搜到,点2是与其直接相连的点,所以这两个点是要被删除的。

    然后就正着跑SPFA啦!

    程序

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN = 10000 + 1, MAXM = 200000 + 1;
     4 int n, m, s, t, Head[MAXN], rH[MAXN], EdgeCount;
     5 bool vis[MAXN], bad[MAXN];
     6 // vis[i]表示i点能否反向BFS搜到
     7 // bad[i]表示是否不符合条件1的点
     8 struct edge
     9 {
    10     int Next, Aim;
    11 }Edge[MAXM], rev[MAXM];
    12 // 分别是原图和反图
    13 void insert(int u, int v)
    14 {
    15     Edge[++EdgeCount] = edge{Head[u], v};
    16     rev[EdgeCount] = edge{rH[v], u};
    17     rH[v] = Head[u] = EdgeCount;
    18 }
    19 // 建立原图和反图
    20 void BFS(int p)
    21 {
    22     for (int i = rH[p]; i; i = rev[i].Next)
    23         if (vis[rev[i].Aim])
    24             continue;
    25         else
    26             vis[rev[i].Aim] = true, BFS(rev[i].Aim);
    27 }
    28 int SPFA()
    29 {
    30     queue<int> Q;
    31     int dist[MAXN];
    32     memset(dist, 0x3F, sizeof(dist));
    33     dist[s] = 0;
    34     Q.push(s);
    35     while (!Q.empty())
    36     {
    37         int u = Q.front();
    38         Q.pop();
    39         for (int i = Head[u]; i; i = Edge[i].Next)
    40         {
    41             int v = Edge[i].Aim;
    42             if (bad[v])
    43                 continue;
    44             // ↑不满足条件1直接continue
    45             if (dist[u] + 1 < dist[v])
    46             {
    47                 Q.push(v);
    48                 dist[v] = dist[u] + 1;
    49             }
    50         }
    51     }
    52     if (dist[t] == 0x3F3F3F3F)
    53         return -1;
    54     else
    55         return dist[t];
    56 }
    57 int main()
    58 {
    59     freopen("road.in","r",stdin);
    60     freopen("road.out","w",stdout);
    61     cin >> n >> m;
    62     for (int i = 1; i <= m; i++)
    63     {
    64         int u, v;
    65         cin >> u >> v;
    66         insert(u,v);
    67     }
    68     cin >> s >> t;
    69     vis[t] = true;
    70     BFS(t);
    71     // ↑反向BFS搜索不与终点相连的点
    72     // ↓枚举vis[i],若vis[i]为假,那么i不与终点相连
    73     // 枚举在反图当中以i为起始点的所有边的终点,这些点都不能满足条件1
    74     for (int i = 1; i <= n; i++)
    75         if (!vis[i])
    76         {
    77             for (int j = rH[i]; j; j = rev[j].Next)
    78                 bad[rev[j].Aim] = true;
    79             bad[i] = true;
    80         }
    81     cout << SPFA() << endl;
    82     return 0;
    83 }
  • 相关阅读:
    深入Android 【一】 —— 序及开篇
    Android中ContentProvider和ContentResolver使用入门
    深入Android 【六】 —— 界面构造
    The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the ser
    Dynamic Business代码片段总结
    对文件的BuildAction以content,resource两种方式的读取
    paraview 3.12.0 windows下编译成功 小记
    百度网盘PanDownload使用Aria2满速下载
    netdata的安装与使用
    用PS给证件照排版教程
  • 原文地址:https://www.cnblogs.com/OIerPrime/p/8443283.html
Copyright © 2011-2022 走看看