首页 > 其他分享 >H - Delivery Route ——dij + scc + topo

H - Delivery Route ——dij + scc + topo

时间:2022-10-21 20:35:37浏览次数:41  
标签:topo 连通 dij int Route Delivery low push dis

H - Delivery Route

题意

给你n个点的一张图,有x条无向边和y条有向边,每条边都有一个边权,但保证负边权不在环中,给你一个起始点,问你起始点每个点的最短路。
因为有负边,所以dij无法直接用,但是题目保证,负边不会出现在环中,所以我们可以强连通缩点,然后就变成了一个dag,对于这个dag,我们就直接topo计算每个强连通分量到s点的距离。
然后我们再在强连通分量中进行dij更新么个点的最短路即可。
对于每个强连通分量,我们不知道里面哪一个点是源点,所以对于每个与其他连通块联通的点都要作为源点计算一次dij
然后对于topo 因为我们已经用tarjan过了 强连通的编号就是逆topo序。

#include<bits/stdc++.h>
#include<array>
#define ll long long
#define all(a) a.begin(),a.end()
using namespace std;

const int N = 2e5 + 505;
const int M = 1e6 + 1;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;

int x, y, s, n;
int dfn[N], low[N], sc, c[N], tot, dis[N];
int vis[N], in[N];
map<pair<int, int>, int>mp;
vector<pair<int, int>>g[N], g2[N];
vector<int>root[N], scc[N];
stack<int>st;

void tarjan(int x) {
    dfn[x] = low[x] = ++tot;
    st.push(x);
    in[x] = 1;
    for (auto [to, w] : g[x]) {
        if (!dfn[to]) {
            tarjan(to);
            low[x] = min(low[x], low[to]);
        }
        else if (in[to]) {
            low[x] = min(low[x], dfn[to]);
        }
    }

    if (low[x] == dfn[x]) {
        sc++;
        while (1) {
            int now = st.top();
            st.pop();
            in[now] = 0;
            c[now] = sc;
            scc[sc].push_back(now);
            if (now == x) break;
        }
    }
}

void dij(int s) {
    for (int i = 1; i <= n; i++) vis[i] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>q;
    q.push({ dis[s], s });
    while (!q.empty()) {
        int x = q.top().second;
        q.pop();
        if (vis[x]) continue;
        vis[x] = 1;
        for (auto [to, w] : g[x]) {
            if (c[to] != c[x]) continue;
            if (dis[to] > dis[x] + w) {
                dis[to] = dis[x] + w;
                q.push({ dis[to], to });
            }
        }
    }
}

void solve() {
    cin >> n >> x >> y >> s;
    int u, v;
    ll w;

    for (int i = 1; i <= x; i++) {
        cin >> u >> v >> w;

        g[u].push_back({ v, w });
        g[v].push_back({ u, w });
    }

    for (int i = 1; i <= y; i++) {
        cin >> u >> v >> w;
        g[u].push_back({ v, w });
    }

    tarjan(s);

    //记录每个强连通分量需要作为源点的点
    for (int i = 1; i <= n; i++) {
        for (auto [to, w] : g[i]) {
            if (c[to] != c[i]) {
                if (!mp[{i, to}]) {
                    // g2[c[i]].push_back({ c[to], w });
                    root[c[to]].push_back(to);
                    mp[{i, to}] = 1;
                }
            }
        }
    }
    root[c[s]].push_back(s);

    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    //topo
    for (int i = sc; i >= 1; i--) {
        for (auto it : root[i]) dij(it);
        for (auto x : scc[i])
            for (auto [to, w] : g[x])
                dis[to] = min(dis[to], dis[x] + w);
    }

    for (int i = 1; i <= n; i++) {
        if (dis[i] >= inf) cout << "NO PATH\n";
        else cout << dis[i] << '\n';
    }

}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int _t = 1;
    //cin >> _t;
    while (_t--) {
        solve();
    }

    return 0;
}

标签:topo,连通,dij,int,Route,Delivery,low,push,dis
From: https://www.cnblogs.com/yaqu-qxyq/p/16814671.html

相关文章

  • 网络篇 route如何添加指向自身IP的路由-有待解决
    问题   现场服务器ping自身IP地址失败尝试添加一条指向自身IP的路由,当然这条路由不会经过网卡,在系统内部传输无效指令routeadd192.168.11.172mask255.255.255.25......
  • react-router-dom v6 使用
    react及相关版本:"react":"^18.2.0","react-dom":"^18.2.0","react-router":"^6.4.2","react-router-dom":"^6.4.2" 实现嵌套路由:目录结构: main.jsximpo......
  • 允许Traceroute探测漏洞解决方法
    允许Traceroute探测漏洞解决方法详细描述本插件使用Traceroute探测来获取扫描器与远程主机之间的路由信息。攻击者也可以利用这些信息来了解目标网络的网络拓扑。解决办......
  • react-router-dom(v6)快速上手
    本篇笔记跟随官方教程而写,把其中连续的步骤碎片化,方便以后忘记的时候直接调用,其中包含了对其他小问题的拓展。创建路由(quick-start)npminstallreact-router-dom在R......
  • Vue 插件:VueRouter
    VueRouter是一个Vue插件,用于实现SPA(singlepagewebapplication)应用。SPA(singlepagewebapplication)应用,即单页面应用。整个应用只有一个.html文件,通常命名为......
  • 三阶段 vue 路由 $route 和 $router 的区别
    1.这是vue-router提供给我们的实例实例的两个属性(api)2.$route是路由对象,一般是获取动态参数|querythis.$route.params.idthis./$route.title ......
  • 升级到React-Router-v6
    前言近期完成了公司新项目的开发,相关的技术栈都用到了最新版本,reactrouter也使用了v6的版本,所以借这个机会自己再梳理下reactrouterv5与v6的区别,以及v6一些新......
  • vue-router中query和params的区别
    一.query和params的知识点理解/data/:id这个路由匹配/data/1,/data/2这里的id叫params/data?id=1/data?id=2这里的id叫queryparams方法传参时,要在路由后面加......
  • vue-10 router路由
    配置:安装使用npminstallvue-router添加路由配置文件,例router.js并在文件中进行路由配置将路由配置添加到main.js中的vue对象使用路由router.js文件//1、引入基......
  • 经常被问到的react-router实现原理详解
    在单页面应用如日中天发展的过程中,备受关注的少了前端路由。而且还经常会被xxx面试官问到,什么是前端路由,它的原理的是什么,它是怎么实现,跳转不刷新页面的...一大堆为什么,......