题目链接

Description

给定一个有 \(n\) 个点和 \(m\) 条边的无向图,其中每一条边 \(e_i\) 都有一个权值记为 \(w_i\) 。

对于给出的两个点 \(a\) 和 \(b\) ,求一条 \(a\) 到 \(b\) 的路径,使得路径上的边权的 \(OR\)(位或)和最小,输出这个值。(也就是说,如果将路径看做边的集合 \(\{e_1,e_2,…,e_k\}\),那么这条路径的代价为 \(w_1\ OR\ w_2\ OR\ …\ OR\ w_k\),现在求一条路径使得其代价最小,输出这个代价。如果不存在这样的路径,输出 \(-1\)。

Input

Easy

\(2\le n \le 10^4, 0 \le m \le 10^6, 0 \le c_i \le 2^{62}-1\)

Hard

\(2\le n \le 10^4, 0 \le m \le 10^6, 0 \le c_i \le 2^{62}-1\)

题解 By zerol

Easy

\(dp[u][k]\) 表示到结点 \(u\) 的代价为 \(k\) 的方案是否存在,然后在图上转移(dfs 一下就好了)。

Hard

假设答案的二进制位全是 \(1\),然后从高位到低位考虑,如果将该位置为 \(0\) 不破坏连通性的话就置为 \(0\),这样肯定最优。

判断连通性可以用 并查集 或者 搜索,反正 \(O(M)\) 就行。

复杂度 \(O(63M)\) 。

对比

稍微回顾一下之前的 bzoj 2115 [Wc2011] Xor 路径最大异或和 线性基

共同点:从高位向低位做,判断当前位能否置为1或0(毕竟都是位运算)

不同点:

Xor那道题是预处理出来一条路径,以及所有可以补充于其上的路径。所以,判断能否置为1即是看能否添加这条路径。

而这道题,因为OR运算的性质,直观想来,添加的路径越少OR和就越小。所以,判断当前位能否置为0即是通过连通性来判断。

Code

Easy

#include <bits/stdc++.h>
#define maxn 1100
#define maxm 10010
using namespace std;
bool vis[maxn][maxn];
struct Edge { int to, ne, w; } edge[maxm << 1];
int tot, ne[maxn];
void add(int u, int v, int w) {
edge[tot] = {v, ne[u], w};
ne[u] = tot++;
}
typedef long long LL;
void dfs(int u, int ors) {
if (vis[u][ors]) return;
vis[u][ors] = true;
for (int i = ne[u]; ~i; i = edge[i].ne) {
int v = edge[i].to;
dfs(v, ors | edge[i].w);
}
}
int main() {
memset(ne, -1, sizeof ne);
int n, m;
scanf("%d%d", &n,&m);
int u, v, w;
for (int i = 0; i < m; ++i) {
scanf("%d%d%d", &u,&v,&w);
add(u,v,w); add(v, u, w);
}
scanf("%d%d", &u, &v);
dfs(u, 0);
for (int i = 0; i <= 1024; ++i) {
if (vis[v][i]) { printf("%d\n", i); return 0; }
}
puts("-1");
return 0;
}

Hard

#include <bits/stdc++.h>
#define maxn 10010
#define maxm 1000010
using namespace std;
typedef long long LL;
vector<int> a[maxn];
struct Edge { int u, v; } edge[maxm];
void add(LL w, int id) {
int cnt = 0;
while (w) {
if (w & 1) a[cnt].push_back(id);
w >>= 1, ++cnt;
}
}
int s, t, n, m, fa[maxn], sz[maxn];
bool exc[maxm], flag[64];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void unionn(int u, int v) {
u = find(u), v = find(v);
if (sz[u] < sz[v]) swap(u, v);
sz[u] += sz[v], fa[v] = u;
}
bool ok(int id) {
memset(exc, 0, sizeof exc);
for (int i = 62; i >= id; --i) {
if (!flag[i]) {
for (auto x : a[i]) exc[x] = true;
}
}
for (int i = 1; i <= n; ++i) fa[i] = i, sz[i] = 1;
for (int i = 0; i < m; ++i) {
if (!exc[i]) unionn(edge[i].u, edge[i].v);
}
return find(s) == find(t);
}
int main() {
scanf("%d%d", &n,&m);
for (int i = 0; i < m; ++i) {
int u, v; LL w;
scanf("%d%d%lld", &u,&v,&w);
edge[i] = {u, v};
add(w, i);
}
scanf("%d%d", &s, &t);
if (!ok(64)) { puts("-1"); return 0; }
LL ans = 0;
for (int i = 62; i >= 0; --i) {
ans <<= 1;
if (!ok(i)) flag[i] = 1, ans |= 1;
}
printf("%lld\n", ans);
return 0;
}

EOJ Monthly 2018.1 F 最小OR路径的更多相关文章

  1. EOJ Monthly 2018.8 D. Delivery Service-树上差分(边权/边覆盖)(边权转点权)(模板题)

    D. Delivery Service 单测试点时限: 2.5 秒 内存限制: 512 MB EOJ Delivery Service Company handles a massive amount ...

  2. EOJ Monthly 2018.2

    A. 坑爹的售票机 题意 用\(1,5,10,25,50,100\)的纸币买\(n\)张单价为\(p\)的船票,且一次性最多买\(k\)张,求钱数恰好时最少需要多少张纸币. Hard: \(n,k,p ...

  3. EOJ Monthly 2018.1

    985月赛,当时鸽了,现在想补一补 A. 石头剪刀布的套路 Time limit per test: 1.0 seconds Memory limit: 256 megabytes 现在有一种石头剪刀 ...

  4. EOJ Monthly 2018.11 D. 猜价格

    猜价格 分两种情况讨论: k≤n,先猜至多 k 次 1,由于回答 <1 肯定是假的,所以可以把剩余系下是哪次错试出来,然后用至多 n 次搞定. k>n,每个数都猜两次,如果两次结果不一样, ...

  5. 【EOJ Monthly 2018.7】【D数蝌蚪】

    https://acm.ecnu.edu.cn/contest/92/problem/D/ D. 数蝌蚪 Time limit per test: 2.0 seconds Memory limit:  ...

  6. EOJ Monthly 2018.7

    准备继续大学acm啦 又要开始愉快的码码码啦 第一次在华东师大OJ上面做题 看来EOJ上的积分体质是假的,我怎么一把上红??? A.数三角形 神tm的防AK题放在A,出题人很不友好啊... 先写了个暴 ...

  7. EOJ Monthly 2018.3

    985月赛我只喜欢ECNU.jpg A. 打工时不可能打工的 Time limit per test: 2.0 seconds Memory limit: 256 megabytes 我 Ayano ...

  8. EOJ Monthly 2018.4

    A. ultmaster 的小迷妹们 Time limit per test: 2.0 seconds Memory limit: 256 megabytes ultmaster 男神和他的小迷妹们准 ...

  9. 【EOJ Monthly 2018.2 (Good bye 2017)】

    23333333333333333 由于情人节要回家,所以就先只放代码了. 此题是与我胖虎过不去. [E. 出老千的 xjj] #include<cstdio> #include<c ...

随机推荐

  1. php扩展开发-哈希表

    什么是哈希表呢?哈希表在数据结构中也叫散列表.是根据键名经过hash函数计算后,映射到表中的一个位置,来直接访问记录,加快了访问速度.在理想情况下,哈希表的操作时间复杂度为O(1).数据项可以在一个与 ...

  2. JZOJ 2136. 【GDKOI2004】汉诺塔

    2136. [GDKOI2004]汉诺塔 (Standard IO) Time Limits: 3000 ms  Memory Limits: 128000 KB  Detailed Limits   ...

  3. Assignment HDU - 2853(二分图匹配 KM 新边旧边)

    传送门: Assignment HDU - 2853 题意:题意直接那松神的题意了.给了你n个公司和m个任务,然后给你了每个公司处理每个任务的效率.然后他已经给你了每个公司的分配方案,让你求出最多能增 ...

  4. 策略模式—Java实现(转)

    1. 现实需求 客户有了新的需求,这时我们直接新增策略即可,改很少的代码.基本符合我们面向对象原则中的开闭原则(对扩展开放,对修改关系),实现了高内聚低耦合. 2. 策略模式定义 策略模式,又叫算法簇 ...

  5. dp专练

    dp练习. codevs 1048 石子归并 区间dp #include<cstdio> #include<algorithm> #include<cstring> ...

  6. 动态加载css,js

    function dynamicLoadCss(url) { var head = document.getElementsByTagName('head')[0]; var link = docum ...

  7. IDEA配置好maven后新建maven项目一直build失败的解决方法

    maven配置了aliyun中央仓库后,IDEA新建maven项目一直出现以下问题: 相信有遇到这个问题的小伙伴很蛋疼,明明maven配置没错,新建项目却一直build失败,为了这个问题我重装过几次I ...

  8. 计算时间复杂度&空间复杂度

    1.下面函数的复杂度是: long foo(long x){ if(x<2) return 1; return x*x*foo(x-1); } 解析: 当n>=2时 foo(n)=n^2* ...

  9. Windows Server 笔记(七):Windows Server 2012 R2 NIC Teaming(NIC组)

    什么是NIC Teaming?         NIC Teaming 就是将两个或更多的网络适配器组合在一起,从而达到容错和带宽聚合作用.NIC Teaming 中的每个网络适配器都是物理存在的(虚 ...

  10. nsfwjs鉴黄识别最小化案例

    3个月前,也就是2月份左右吧,Github上出现一个开源项目: Infinite Red, Inc.工作室宣布开源旗下基于tensorflow的tfjs的鉴黄小工具 据说是从15000张图片中 进行机 ...