首页 > 其他分享 >[ABC245G] Foreign Friends 题解

[ABC245G] Foreign Friends 题解

时间:2023-10-11 23:34:22浏览次数:47  
标签:dist int 题解 st heap push ABC245G include Friends

[ABC245G] Foreign Friends 题解

想法

考虑所有颜色相同的弱化版。

这种情况下,只需要把所有特殊点都推入队列之后跑多源 Dijkstra 即可。

思路

正解与上述做法大致相同。

如果有颜色限制,那么可以考虑这个神仙思路:

把所有特殊点的颜色用二进制表示,对于每一位,这一位是 \(0\) 的特殊点作为源点跑 Dijkstra,只更新这一位是 \(1\) 的点,对于这一位是 \(1\) 的特殊点同理,这样就对每一个特殊点统计了它与这一位颜色不同的点的距离。

这样一定可以迭代找到最短的距离,因为如果存在一个这样的路径,那么当前点和路径端点的颜色的二进制表示一定有一位不相同,因此它们的距离已经被统计过了,所以上述算法一定能够找到最优解。

时间复杂度:\(O(m\log m\log k)\)。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#define int long long
#define x first
#define y second
using namespace std;
using PII = pair<int, int>;
const int N = 2e5 + 10;

int n, m, k, l, c[N], dist[N], f[N];
vector<PII> g[N];
vector<int> sp;
bool st[N];

priority_queue<PII, vector<PII>, greater<PII> > heap;
void dijkstra(int x, int o) {
    memset(st, 0, sizeof st);
    while(heap.size()) {
        int t = heap.top().y; heap.pop();
        if(st[t]) continue;
        st[t] = 1;
        for(auto v : g[t]) {
            if(dist[v.x] > dist[t] + v.y) {
                dist[v.x] = dist[t] + v.y;
                if((c[v.x] >> x & 1) == o) f[v.x] = min(f[v.x], dist[v.x]);
                heap.push({dist[v.x], v.x});
            }
        }
    }
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> m >> k >> l;
    for(int i = 1; i <= n; i ++) cin >> c[i];
    for(int i = 1, x; i <= l; i ++) cin >> x, sp.push_back(x);
    for(int i = 1, a, b, c; i <= m; i ++) {
        cin >> a >> b >> c;
        g[a].push_back({b, c}), g[b].push_back({a, c});
    }
    memset(f, 0x3f, sizeof f);
    for(int i = 0; i <= 17; i ++) {
        while(heap.size()) heap.pop();
        memset(dist, 0x3f, sizeof dist);
        for(int u : sp) if(c[u] >> i & 1) heap.push({0, u}), dist[u] = 0;
        dijkstra(i, 0);
        while(heap.size()) heap.pop();
        memset(dist, 0x3f, sizeof dist);
        for(int u : sp) if((c[u] >> i & 1) == 0) heap.push({0, u}), dist[u] = 0;
        dijkstra(i, 1);
    }
    for(int i = 1; i <= n; i ++) {
        if(f[i] <= 4e18) cout << f[i] << ' ';
        else cout << -1 << ' ';
    }
    
    return 0;
}

标签:dist,int,题解,st,heap,push,ABC245G,include,Friends
From: https://www.cnblogs.com/MoyouSayuki/p/17758496.html

相关文章

  • CF882E1+CF1882E2 Two Permutations 题解-构造题
    CF882E1+CF1882E2TwoPermutations题解-构造题哇,人类智慧,太智慧了。。。此题作为20231010联考的T3。感觉赛时根本没有去往这方面想。CF1882E1CF1882E2E1是简单版,就是没有要求操作数最小化。E1-EasyVersion方法1首先考虑没有次数限制的,对于单独的每一个串的情况。......
  • [USACO17JAN] Promotion Counting P 题解
    [USACO17JAN]PromotionCountingP题解前言好久没写题解了,今天趁我心情好赶紧水一篇。思路首先拿到这题,关键词检索:子树,比\(p_i\)大的,树状数组!现在考虑如何去掉其他子树的贡献……emm,我直接在算贡献的时候去掉其他子树的贡献不就好了!当然,暴力去贡献复杂度肯定爆炸,这里考虑......
  • [USACO08FEB]meteor Shower S题解(bfs)
    题目描述贝茜听说一场特别的流星雨即将到来:这些流星会撞向地球,并摧毁它们所撞击的任何东西。她为自己的安全感到焦虑,发誓要找到一个安全的地方(一个永远不会被流星摧毁的地方)。如果将牧场放入一个直角坐标系中,贝茜现在的位置是原点,并且,贝茜不能踏上一块被流星砸过的土地。根据预......
  • FileZilla 超时连接失败问题解决办法
    1.确保ubuntu支持FTP   就是安装ssh。      首先查看你有没有:sudops-e|grepssh红色箭头存在就代表你有的!如果没有那就去安装吧!2.确保ubuntu和windouws都关闭防火墙!【1】ubuntu打开终端输入:sudoufwdisable就会出现【2】windows中在搜索框中搜索防火墙:关闭......
  • 网络规划设计师真题解析--SNMP管理(安全威胁)
    在网络管理中要防范各种安全威胁。在SNMP管理中,无法防范的安全威胁是(35)。A.篡改管理信息:通过改变传输中的SNMP报文实施未经授权的管理操作B.通信分析:第三者分析管理实体之间的通信规律,从而获取管理信息C.假冒合法用户:未经授权的用户冒充授权用户,企图实施管理操作D.截获:未经授权......
  • P1457 [USACO2.1] 城堡 The Castle 题解
    分析感觉没有蓝题难度一道bfs题目,相较于大部分bfs题,它较为复杂,但分析一下还是很好水过的。建立墙时,可以用三维数组,\(wall_{~i,~j,~pos}\)表示第\(i\)行第\(j\)列\(pos\)方向有墙。观察发现,\(8=2^3,4=2^2,2=2^1,1=2^1\),于是可以用位运算快速储存。这里给出......
  • Ubuntu无法联网问题解决
    前言会有不同种原因导致系统无法联网,我遇到的可能只是其中一种,建议多问问ChatGPT,每一步遇到的问题问问人家应该能解决我遇到的情况是,之前一直能联网,然后一段时间不登就连不上网,然后又好了,然后又连不上网因此也把我这种情况的解决方案记录一下,以备不时之需   解决步骤......
  • Shuffle 题解
    Shuffle题目大意给定一个长度为\(n\)的01序列\(a\),你可以进行至多一次以下操作:选定\(a\)的一个连续段,满足连续段内恰好有\(k\)个\(1\),将该连续段任意排列。问能产生多少种不同的01序列。思路分析(这题\(n\)完全可以开到\(10^6\)或是\(10^7\),因为存在\(O(......
  • Hadoop问题解决(5)
    当一个HDFS系统同时处理许多个并行的put操作,往HDFS上传数据时,有时候会出现dfsclient端发生socket链接超时的报错,有的时候甚至会由于这种原因导致最终的put操作失败,造成数据上传不完整。log类似如下:Alldatanodes ***arebad.Aborting...类似这样的错误,常常会在并行的put操作......
  • Debian12安装MySQL8实践及问题解决方案
    Debian12安装MySQL数据库,常规操作:sudoaptsearchmysql&sudoaptinstallmysql,肯定是行不通的,因为没有安装包。把我的安装过程以及遇到问题的解决方案记录下来,供大家借鉴。第一步更新系统、下载软件包命令如下:sudoaptupdatewgethttps://dev.mysql.com/get/mysql-apt-co......