【题目链接】

  • 点击打开链接

【思路要点】

  • 首先,我们显然需要令所有边为 AAA 进行一次询问,得到 sss 到 ttt 的最短路。
  • 我们可以从找到最短路上的一个点出发:
  • 令所有与编号在 [1,mid][1,mid][1,mid] 中的点相邻的边为 BBB ,其余边为 AAA ,通过判断最短路是否不变,我们可以知道 sss 到 ttt 间是否存在一条不经过编号在 [1,mid][1,mid][1,mid] 中的点的最短路。因此通过二分,我们可以在 Log2NLog_2NLog2​N 次操作内找到最短路上的一个点 rootrootroot 。
  • 以 rootrootroot 为根,进行 BFSBFSBFS ,显然 sss 和 ttt 中必然有一个是其间任何一条最短路上 BFSBFSBFS 序最大的点。令所有与 BFSBFSBFS 序在 [mid+1,N][mid+1,N][mid+1,N] 中的点相邻的边为 BBB ,其余边为 AAA ,通过判断最短路是否不变,我们可以知道 sss 和 ttt 中是否有至少一个的 BFSBFSBFS 序在 [mid+1,N][mid+1,N][mid+1,N] 中。因此通过二分,我们可以在 Log2NLog_2NLog2​N 次操作内找到 sss 和 ttt 中的一个。
  • 不妨令找到了 sss ,以 sss 为根,进行 BFSBFSBFS ,同样通过二分,我们可以找到 ttt 。
  • 时间复杂度 O(MLogN)O(MLogN)O(MLogN) ,使用操作次数不超过 3Log2N+13Log_2N+13Log2​N+1 ,实测最多使用操作 515151 次,得分 909090 。
  • 我们也可以从找到最短路上的一条边出发:
  • 令所有与编号在 [1,mid][1,mid][1,mid] 中的边为 BBB ,其余边为 AAA ,通过判断最短路是否不变,我们可以知道 sss 到 ttt 间是否存在一条不经过编号在 [1,mid][1,mid][1,mid] 中的边的最短路。因此通过二分,我们可以在 Log2NLog_2NLog2​N 次操作内找到最短路上的一条边 (rootx,rooty)(rootx,rooty)(rootx,rooty) 。
  • 由于 (rootx,rooty)(rootx,rooty)(rootx,rooty) 在最短路上,有 dist(s,rootx)≠dist(s,rooty)dist(s,rootx)\ne dist(s,rooty)dist(s,rootx)̸​=dist(s,rooty) 且 dist(t,rootx)≠dist(t,rooty)dist(t,rootx)\ne dist(t,rooty)dist(t,rootx)̸​=dist(t,rooty) ,因此,以 rootx,rootyrootx,rootyrootx,rooty 为根,分别进行 BFSBFSBFS ,我们可以将点集分成两组,一组离 rootxrootxrootx 更近,另一组离 rootyrootyrooty 更近, sss 和 ttt 一定分别在其中一组中,用上文中的二分解决即可。
  • 时间复杂度 O(MLogN)O(MLogN)O(MLogN) ,使用操作次数不超过 Log2M+Log2S+Log2T+1(S+T≤N)Log_2M+Log_2S+Log_2T+1\ (S+T≤N)Log2​M+Log2​S+Log2​T+1 (S+T≤N) ,实测最多使用操作 505050 次,得分 100100100 。

【代码】

// 90 points Version - 3LogN + 1
#include "highway.h"
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
typedef long long ll;
int n, m, costA, costB;
int s, t, dis, root;
int dist[MAXN], num[MAXN], q[MAXN];
vector <int> u, v;
vector <int> a[MAXN], input;
void work(int l, int r) {if (l == r) {root = l;return;}int mid = (l + r) / 2;for (int i = 0; i < m; i++)if ((u[i] >= 1 && u[i] <= mid) || (v[i] >= 1 && v[i] <= mid)) input[i] = 1;else input[i] = 0;if (ask(input) != 1ll * dis * costA) work(l, mid);else work(mid + 1, r);
}
void bfs(int from) {memset(dist, -1, sizeof(dist));int l = 1, r = 1, timer = 1;q[1] = from, dist[from] = 0, num[from] = 1;while (l <= r) {int tmp = q[l++];for (unsigned i = 0; i < a[tmp].size(); i++)if (dist[a[tmp][i]] == -1) {dist[a[tmp][i]] = dist[tmp] + 1;q[++r] = a[tmp][i];num[a[tmp][i]] = ++timer;}}
}
void find_pair(int tn, vector <int> tu, vector <int> tv, int ta, int tb) {n = tn, costA = ta, costB = tb;m = tu.size(), u = tu, v = tv;input.resize(m);dis = ask(input) / costA;for (int i = 0; i < m; i++) {tu[i]++, u[i]++, tv[i]++, v[i]++;int x = tu[i], y = tv[i];a[x].push_back(y);a[y].push_back(x);}work(1, n);bfs(root);int l = 2, r = n;while (l < r) {int mid = (l + r + 1) / 2;for (int i = 0; i < m; i++)if (num[u[i]] >= mid || num[v[i]] >= mid) input[i] = 1;else input[i] = 0;if (ask(input) != 1ll * dis * costA) l = mid;else r = mid - 1;}bfs(s = q[l]);static int p[MAXN], pos[MAXN]; int tot = 0;for (int i = 1; i <= n; i++)if (dist[i] == dis) p[i] = ++tot, pos[tot] = i;else p[i] = 0;l = 1, r = tot;while (l < r) {int mid = (l + r) / 2;for (int i = 0; i < m; i++)if ((p[u[i]] >= l && p[u[i]] <= mid) || (p[v[i]] >= l && p[v[i]] <= mid)) input[i] = 1;else input[i] = 0;if (ask(input) != 1ll * dis * costA) r = mid;else l = mid + 1;}t = pos[l];answer(s - 1, t - 1);
}
// 100 points Version - LogS + LogT + LogM + 1 (S + T == N)
#include "highway.h"
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
typedef long long ll;
int n, m, costA, costB;
int s, t, dis, rootx, rooty;
int distx[MAXN], numx[MAXN], qx[MAXN];
int disty[MAXN], numy[MAXN], qy[MAXN];
vector <int> u, v;
vector <int> a[MAXN], input;
void work(int l, int r) {if (l == r) {rootx = u[l];rooty = v[l];return;}int mid = (l + r) / 2;for (int i = 0; i < m; i++)if (i <= mid) input[i] = 1;else input[i] = 0;if (ask(input) != 1ll * dis * costA) work(l, mid);else work(mid + 1, r);
}
void bfs(int from, int *dist, int *q, int *num) {for (int i = 1; i <= n; i++)dist[i] = -1;int l = 1, r = 1, timer = 1;q[1] = from, dist[from] = 0, num[from] = 1;while (l <= r) {int tmp = q[l++];for (unsigned i = 0; i < a[tmp].size(); i++)if (dist[a[tmp][i]] == -1) {dist[a[tmp][i]] = dist[tmp] + 1;q[++r] = a[tmp][i];num[a[tmp][i]] = ++timer;}}
}
void find_pair(int tn, vector <int> tu, vector <int> tv, int ta, int tb) {n = tn, costA = ta, costB = tb;m = tu.size(), u = tu, v = tv;input.resize(m);dis = ask(input) / costA;for (int i = 0; i < m; i++) {tu[i]++, u[i]++, tv[i]++, v[i]++;int x = tu[i], y = tv[i];a[x].push_back(y);a[y].push_back(x);}work(0, m - 1);bfs(rootx, distx, qx, numx);bfs(rooty, disty, qy, numy);static int p[MAXN], pos[MAXN]; int tot = 0;for (int i = 1; i <= n; i++)if (distx[qx[i]] < disty[qx[i]]) p[qx[i]] = ++tot, pos[tot] = qx[i];else p[qx[i]] = 0;int l = 1, r = tot;while (l < r) {int mid = (l + r + 1) / 2;for (int i = 0; i < m; i++)if (p[u[i]] >= mid || p[v[i]] >= mid) input[i] = 1;else input[i] = 0;if (ask(input) != 1ll * dis * costA) l = mid;else r = mid - 1;}s = pos[l];tot = 0;for (int i = 1; i <= n; i++)if (disty[qy[i]] < distx[qy[i]]) p[qy[i]] = ++tot, pos[tot] = qy[i];else p[qy[i]] = 0;l = 1, r = tot;while (l < r) {int mid = (l + r + 1) / 2;for (int i = 0; i < m; i++)if (p[u[i]] >= mid || p[v[i]] >= mid) input[i] = 1;else input[i] = 0;if (ask(input) != 1ll * dis * costA) l = mid;else r = mid - 1;}t = pos[l];answer(s - 1, t - 1);
}

【LOJ2867】「IOI2018」高速公路收费相关推荐

  1. 「IOI2018」Highway 高速公路收费

    目录 「IOI2018」Highway 高速公路收费 题目描述: 实现细节: 输入格式: 输出格式: 样例: 数据范围与提示: 子任务: 题解: Code 「IOI2018」Highway 高速公路收 ...

  2. 智能汽车进入「开源」时代

    智能汽车即将进入"开源"时代,这将深刻影响传统汽车供应链体系. 传统意义上,我们理解的开源,是源代码.免费.白盒,但实际上,在具体的商业化应用中,则是为满足业务需求和解决业务问题而 ...

  3. AI 复活「她」! GPT-3 帮美国小哥复刻逝去未婚妻,但又夺走她……

    整理 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 今年 7 月,一名33岁的美国小哥 Joshua Barbeau 在未婚妻去世后,根据她在 Facebook 和 twitter ...

  4. 吴恩达老师,被曝靠「教书」实现首个IPO上市,估值50亿美元

    贾浩楠 发自 凹非 寺 量子位 报道 | 公众号 QbitAI 「连续创业者」吴恩达老师,被曝旗下企业将首次上市! 这家外界估值50亿美金的公司,不是自动驾驶,不是行业垂直方案. 而是吴恩达2012年 ...

  5. 一篇文章7.4万,Nature 33种期刊开放获取新政引争议,社区斥其「寄生虫」

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 来自:机器之心 Springer Nature 迈向开放获取之路,然而每篇 OA 文章 ...

  6. 19岁「黑客」连续破解25辆特斯拉:远程控制门窗、灯光、音乐,还能直接开走...

    来源:机器之心 从事网络安全研究的 19 岁德国男孩 David Colombo 最近有一个大发现. 他在为一家法国公司进行安全审查时注意到,该公司网络中的一个软件程序泄露了公司 CTO 所驾驶的特斯 ...

  7. 谷歌相册也不能无限白嫖了,「地主家」也烧不起免费网盘

    木易 发自 凹非寺  量子位 报道 | 公众号 QbitAI 连Google都撑不住了. Google相册宣布:从2021年6月1日开始,将停止提供免费的无限制存储空间. 这意思,是不让「白嫖」了? ...

  8. 如何系统地理解「交易平台」?

    最近四年一直在做交易平台的项目,期间遇到了很多困难,让我持续地思考一个关键问题:"交易平台的价值是什么?应该怎么去理解它?" 在思考这个问题的过程中,我发现不论自己如何努力,都始终 ...

  9. 开源的恶果,程序员正在「自掘坟墓」

    大家好,我是校长. 最近开源社区里发生了一件大事,在 IT 圈引起了轰动,那就是:faker.js 开源项目的作者删除了该项目的所有代码. 01 事情是这样的 作为一个著名的 nodejs 工具库,F ...

最新文章

  1. 使用python爬取视频
  2. [ACM] hdu 1671 Phone List (字典树)
  3. VR开发从何入手的实战分享
  4. C编译器、链接器、加载器详解
  5. 关于Xbox live及其在中国的使用
  6. java怎么获取控制台内容的类型_java 怎么获取控制台的数据并且输出到GUI上
  7. 为什么商家数字化离不开交易平台
  8. SpringBoot+拦截器+自定义异常+自定义注解+全局异常处理简单实现接口权限管理...
  9. 【Java习作】KWIC模拟
  10. duri oracle 连接字符串_Oracle连接字符串大全
  11. SCCM 2012 SP1系列(一)先决条件准备-1
  12. java抛异常 代替返回_Java使用和C++类似的异常处理
  13. ie浏览器打不开闪退_点开IE浏览器的时候总是闪退
  14. 12.15 小程序验证码点击刷新
  15. DM - Manager工具
  16. mysql封机器码,lol机器码解除(同理支持市面上任意一款游戏)解机器码
  17. 显卡天梯图vs专业计算卡丽台T4,v100vs混合精度训练
  18. es查询简单场景问题小记
  19. 测验6: 组合数据类型 (第6周) + 练习6: 组合数据类型 (第6周)
  20. 多目标优化-测试问题及其Pareto前沿

热门文章

  1. 使用爬虫爬取某电影分享网站最新电影链接 -- 基于Python Requests库
  2. Node.js 动手实现简单的模板引擎(列表渲染)
  3. QQ三国华容道拼图脚本(半成品,成功率不高)
  4. 1196 找到特殊的四位数
  5. max232c语言,串行口通信(STC89C52+MAX232):串行口通信硬件设计详解
  6. 液晶显示器LCD与LED的区别
  7. 华三设备常用调试命令
  8. flume学习之一 是什么,主要应用在什么场景
  9. [转]不是高手别碰我,VIM怎么舍得我难过
  10. 如何在redhat下安装办公软件(openoffice)