首页 > 其他分享 >AcWing342. 道路与航线

AcWing342. 道路与航线

时间:2022-12-22 22:11:19浏览次数:63  
标签:连通 航线 dist int bid AcWing342 道路 heap id

原题链接

解题思路

这题用\(SPFA\)会被卡,所以我们不能用\(SPFA\)
但是观察数据我们可以发现对于道路,\(0≤C_i≤10^{5}\)
所以对于每个连通块(内部不存在航线),我们可以用\(Dijkstra\)算法进行求解,因为不存在负权边,而\(Dijkstra\)算法的时间较为稳定,所以对于连通块内部的最短路,我们采用\(Dijkstra\)
块内问题解决了,但是块间呢
保证如果有一条航线可以从\(A_i\) 到 \(B_i\),那么保证不可能通过一些道路和航线从 \(B_i\) 回到 \(A_i\)。
我们将每个连通块看做一个大点
那么根据上述性质,我们可以得到这张由大点为点,航线为边的图是一张拓扑图\((DAG)\)
那么\(DAG\)的最短路我们可以按照它的拓扑序扫描求出最短路
为什么呢
因为我们利用拓扑序进行\(DP\),那后来的节点一定是无法更新前面的节点,这样就可以确保无后效性,因此可以正确求出最短路

解题步骤

1.先输入所有的双向道路,然后用\(dfs\)求出所有的连通块,用\(id[]\)数组统计每个数所在的连通块编号,用一个\(vector\)<\(int\)> \(block[]\)来保存每个编号的连通块里存的点
2.输入所有的航线,再输入的同时可以统计每个连通块的入度
3.拓扑排序
4.按照拓扑序对每个连通块进行\(Dijkstra\)算法
5.\(Dijkstra\)步骤:
(1)每次从堆中取出一个点\(t\)
(2)遍历\(t\)的所有出边,同一个连通块的进行松弛操作,不同连通块的将对方连通块入度\(-1\),如果\(-1\)后连通块的入度为0,插入拓扑序队列中(所以拓扑序的队列要开成全局的)

代码

#include <iostream>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;
typedef pair<int, int> PII;

const int N = 25010, M = 2e5 + 10, INF = 0x3f3f3f3f;
int h[N], e[M], w[M], ne[M], idx;
int dist[N], id[N], st[N], din[N];
int n, mr, mp, S, bcnt;

vector<int> block[M];
queue<int> q;

void add(int a, int b, int c) 
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}

void dfs(int u, int bid) 
{
    id[u] = bid, block[bid].push_back(u);

    for (int i = h[u]; ~i; i = ne[i]) 
    {
        int j = e[i];
        if (!id[j]) dfs(j, bid);
    }
}

void Dijkstra(int bid) 
{
    priority_queue<PII, vector<PII>, greater<> > heap;

    for (auto u : block[bid]) 
        heap.push({dist[u], u});

    while (heap.size()) 
    {
        auto t = heap.top().second; heap.pop();

        if (st[t]) continue ;
        st[t] = true ;

        for (int i = h[t]; ~i; i = ne[i]) 
        {
            int j = e[i];
            if (dist[j] > dist[t] + w[i]) 
            {
                dist[j] = dist[t] + w[i];
                if (id[j] == id[t]) heap.push({dist[j], j});
            }

            if (id[j] != id[t] && -- din[id[j]] == 0) q.push(id[j]);
        }
    }
}

void topsort() 
{
    memset(dist, 0x3f, sizeof dist);
    dist[S] = 0;

    for (int i = 1; i <= bcnt; i ++ ) 
        if (!din[i]) q.push(i);

    while (q.size()) 
    {
        int t = q.front(); q.pop();
        Dijkstra(t);
    }
}

int main()
{
    scanf("%d%d%d%d", &n, &mr, &mp, &S);

    memset(h, -1, sizeof h);
    memset(st, 0, sizeof st);

    while (mr -- ) 
    {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        add(u, v, w), add(v, u, w);
    }

    for (int i = 1; i <= n; i ++ ) 
        if (!id[i]) dfs(i, ++ bcnt);

    while (mp -- ) 
    {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        add(u, v, w), din[id[v]] ++ ;
    }

    topsort();

    for (int i = 1; i <= n; i ++ ) 
        if (dist[i] > INF / 2) puts("NO PATH");
        else printf("%d\n", dist[i]);

    return 0;
}

标签:连通,航线,dist,int,bid,AcWing342,道路,heap,id
From: https://www.cnblogs.com/StkOvflow/p/16999699.html

相关文章

  • 华普物联 道路交通预警解决方案
    道路交通预警有较多分类产品,首先介绍道路警示、雾灯诱导类产品。行车安全智慧化预警系统采用物联网、云计算、人工智能、大数据等技术,对道路行人、驾驶员有警示和提示的作......
  • 坎坷道路-程序员必须先让自己的心灵强大起来
    1、什么是君子讲究衣饰打扮这是无可厚非的,然而刻意地追求时尚的新潮未必就是时代的弄潮儿。一个人真正的光辉之处在于其人有闪光的思想,超......
  • 道路游戏——题解
    单调队列优化-道路游戏[NOIP2009普及组]道路游戏题目描述小新正在玩一个简单的电脑游戏。游戏中有一条环形马路,马路上有\(n\)个机器人工厂,两个相邻机器人工厂之间......
  • 2236. 伊基的故事 I - 道路重建
    题目链接2236.伊基的故事I-道路重建伊基是一个小国–凤凰国的国王。凤凰国是如此之小,以至于只有一个城市负责日常商品的生产,并使用公路网将商品运送到首都。伊基......
  • 【SSL 1588】猜道路(图论)
    猜道路题目链接:SSL1588题目大意给你n个点之间的最短路径,要你找到原来图上路径的总长度最短可以是多少,如果没有满足的图则输出-1。思路首先至于判断满足这个很简单......
  • 进阶道路
    C语言要想达到大厂标准,重点是指针和内存管理,以后可以去做服务器开发,后台开发,就包括驱动开发,进阶书籍《CPrimerPlus》、《C和指针》、《C专家编程》,但是由于C++比C多了面......
  • Cocos2d-x实战-手把手教你上线项目-迷失航线-关东升-专题视频课程
    Cocos2d-x实战-手把手教你上线项目-迷失航线—32235人已学习课程介绍        本课程介绍一个实际的手机游戏,使用Cocos2d-x引擎从设计到开发过程。了解当下为流行的......
  • 道路交通:汽车剐蹭处理方法
    一、轻微剐蹭,对方全责1、勿关汽车,否则行车记录仪可能会突然失忆(待测试),下车前开手机录音;2、待安全后下车拍照,需包括对方人、双方车牌、碰撞位置左右各一;3、轻微事故且定......
  • 数代接力飞越数千公里的帝王斑蝶,愿风儿指引你道路,愿星辰照亮你方向
    文/ ​​王不留​​(微信公众号:考研英语笔记)插播昨天文章《​​欧洲进入“寒冬”,迎来愁云惨淡的圣诞消费季|经济学人全球早报精选20211208​​》中一个知识点的修订。感......
  • keepalived实现mycat高可用问题排查;道路坎坷,布满荆棘,定让你大吃一惊!
    开心一刻医院里,一母亲带着小女孩打针小女孩:“妈妈我不想打针,疼!”妈妈:“宝贝儿听话,这里这么多护士阿姨,咱们找个打针不疼的”小女孩:“那哪个阿姨打针不疼呢?”......