[ABC245G] Foreign Friends 题解
[ABC245G] Foreign Friends 题解
想法
考虑所有颜色相同的弱化版。
这种情况下,只需要把所有特殊点都推入队列之后跑多源 Dijkstra 即可。
思路
正解与上述做法大致相同。
如果有颜色限制,那么可以考虑这个神仙思路:
把所有特殊点的颜色用二进制表示,对于每一位,这一位是
这样一定可以迭代找到最短的距离,因为如果存在一个这样的路径,那么当前点和路径端点的颜色的二进制表示一定有一位不相同,因此它们的距离已经被统计过了,所以上述算法一定能够找到最优解。
时间复杂度:
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端