【Luogu】每日一题——Day20. P4366 [Code+#4] 最短路 (图论)

P4366 [Code+#4] 最短路 - 洛谷

题目:

思路:

其实是找性质

本题我们首先可以想到的就是建图然后跑最短路,但是数据给的很大,如果直接暴力建图显然不行,考虑一些特殊情况需要建图

考虑 1 -> 7 这个例子

我们一种走法是直接从 1->7,那么二进制下就是 001 -> 111,花费就是 6 * c

另一种走法就是考虑走中间节点,具体的从 001 -> 011 -> 111,花费一样也是 6 * c

可以看出,只要两个数有超过一位不同,那么就能通过中间节点走到终点

具体的,我们每个数都建一条和自己有一位不同的边,那么其连接的点就是 i ^ ,即只有一位不同,这个位可以是 32 位中的任意一位,所以价值就是 c * (i ^ (i ^ )) = c *

所以就从 n*n 变成了 n*logn 的建图了,顺利解决

代码:

cpp 复制代码
#include <iostream>
#include <algorithm>
#include<cstring>
#include <iomanip>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <utility>
#include <array>
#include <tuple>
using namespace std;
#define int long long
#define yes cout << "YES" << endl
#define no cout << "NO" << endl

vector<vector<pair<int,int>>> g(100005);
int n, m, c;
int dis[100005];
int s, e;

void Init()
{
    for (int i = 0; i <= n; i++)
    {
        for (int j = 1; j <= n; j <<= 1)
        {
            if ((i ^ j) > n)
                continue;
            g[i].push_back({ i ^ j, j * c });
        }
    }
}

void fuc()
{
    dis[s] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
    pq.push({ 0,s });
    while (!pq.empty())
    {
        auto t = pq.top();
        pq.pop();
        if (t.second == e || dis[t.second] < t.first)
        {
            continue;
        }
        for (auto & son : g[t.second])
        {
            int v = son.first;
            int cost = son.second;
            if (dis[v] > t.first + cost)
            {
                dis[v] = t.first + cost;
                pq.push({ t.first + cost ,v });
            }
        }
    }
}

void solve()
{
    cin >> n >> m >> c;
    for (int i = 0; i < m; i++)
    {
        int u, v, c;
        cin >> u >> v >> c;
        g[u].push_back({ v, c });
    }
    cin >> s >> e;
    Init();
    memset(dis, 0x3f, sizeof dis);
    fuc();
    cout << dis[e] << endl;
}
signed main()
{
    //cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    //cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
相关推荐
搂鱼11451410 分钟前
GJOI 11.10 题解
算法
爱睡觉的咋14 分钟前
openGauss × AI:打造一个能识图、能讲解、还能推荐的智慧博物馆导览师
算法
视觉AI37 分钟前
一帧就能“训练”的目标跟踪算法:通俗理解 KCF 的训练机制
人工智能·算法·目标跟踪
2301_795167201 小时前
玩转Rust高级应用 如何理解 Rust 实现免疫数据竞争的关键是Send 和 Sync 这两个 trait
开发语言·算法·rust
Blossom.1181 小时前
AI Agent记忆系统深度实现:从短期记忆到长期人格的演进
人工智能·python·深度学习·算法·决策树·机器学习·copilot
Q741_1471 小时前
C++ 面试高频考点 链表 迭代 递归 力扣 25. K 个一组翻转链表 每日一题 题解
c++·算法·链表·面试·递归·迭代
_fairyland2 小时前
数据结构 力扣 练习
数据结构·考研·算法·leetcode
Neil今天也要学习2 小时前
永磁同步电机无速度算法--基于三阶LESO的反电动势观测器
算法·1024程序员节
机器学习之心2 小时前
NGO-VMD北方苍鹰算法优化变分模态分解+皮尔逊系数+小波阈值降噪+信号重构,MATLAB代码
算法·matlab·重构·信号重构·ngo-vmd·皮尔逊系数·小波阈值降噪
橘颂TA2 小时前
【剑斩OFFER】算法的暴力美学——山脉数组的蜂顶索引
算法·leetcode·职场和发展·c/c++