zoukankan      html  css  js  c++  java
  • 【NOIP2014提高组】寻找道路

    https://www.luogu.org/problem/show?pid=2296

    满足条件的路径:路径上的所有点的出边所指向的点都与终点连通。
    反过来,不满足条件的路径:路径上至少一点的出边所指向的点不与终点连通。
    考虑把所有与终点不连通的点以及指向他们的点都删掉,再一遍BFS求出最短路径。

    具体做法:
    对原图的转置图(将所有边的方向翻转得到的图)从终点开始一遍搜索,把传达不到的爱恋点以及在转置图中它们的所有出点全部标记。注意用两种不同的标记,否则会混乱。
    最后在原图跑一遍BFS求出最短路径,有标记的点都不管。

    #include <iostream>
    #include <vector>
    #include <queue>
    #define maxn 10005
    using namespace std;
    int n, m, s, t;
    vector<int> g[maxn], gt[maxn];
    bool visited[maxn];
    int dist[maxn];
    int mark[maxn]; // 0/1表示该点与终点不连通/联通,-1表示该点指向标记0的点
    void dfs(int k)
    {
        mark[k] = 1;
        for (int i = 0; i < gt[k].size(); i++)
        {
            if (!visited[gt[k][i]])
            {
                visited[gt[k][i]] = true;
                dfs(gt[k][i]);
            }
        }
    }
    void bfs()
    {
        queue<int> q;
        q.push(s);
        while (!q.empty() && dist[t] == 0)
        {
            int k = q.front();
            q.pop();
            if (mark[k] == 1)
            {
                for (int i = 0; i < g[k].size(); i++)
                {
                    if (!dist[g[k][i]])
                    {
                        dist[g[k][i]] = dist[k] + 1;
                        q.push(g[k][i]);
                    }
                }
            }
        }
    }
    int main()
    {
        cin >> n >> m;
        int a, b;
        for (int i = 1; i <= m; i++)
        {
            cin >> a >> b;
            if (a != b)
            {
                g[a].push_back(b);
                gt[b].push_back(a);
            }
        }
        cin >> s >> t;
        dfs(t);
        for (int i = 1; i <= n; i++)
        {
            if (mark[i] == 0)
            {
                for (int j = 0; j < gt[i].size(); j++)
                {
                    mark[gt[i][j]] = -1;
                }
            }
        }
        bfs();
        cout << (dist[t] > 0 ? dist[t] : -1) << endl;
        return 0;
    }
  • 相关阅读:
    Python自动化运维之1、Python入门
    Github使用教程
    Windows 托盘区域显示图标
    VS 2013 打包程序教程
    UML类图简单介绍
    crontab定时任务
    软硬链接的区别和重点
    linux运维之NFS服务器配置
    怎么样让Win10可以ping通?
    VM虚拟机Linux克隆后网卡的相关操作!
  • 原文地址:https://www.cnblogs.com/ssttkkl/p/7530428.html
Copyright © 2011-2022 走看看