有一个 个点的竞赛图,其中 的入度为 ,你可以进行交互,每次询问点对 ,回答是否存在 到 的路径,如果回答为 "Yes" 则不能再询问,否则可以继续询问。
求出一个点对 ,其中 可以互相到达,并且 最大。
。
提供一个 且不需要询问的做法。
简单来说是:按照入度从小到大排序,如果到前 个的入度和恰好为 ,则出现了一个新的强连通分量,假设上一次符合条件的是 ,则 构成了一个新的强连通分量。
这样遍历一遍就可以求出每个强连通分量里有哪些点,就能统计出答案了。
排序选择计数排序,时间复杂度 。
//Code by do_while_true
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#define pp std::pair<int,int>
#define mp std::make_pair
#define fir first
#define sec second
template <typename T>
T& read(T& r) {
r = 0; bool w = 0; char ch = getchar();
while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
return r = w ? -r : r;
}
const int N = 510;
int n, mx = -1, lst, sum, ansu, ansv, ct;
std::vector<int>vec[N];
pp a[N];
signed main() {
read(n);
for(int i = 1, x; i <= n; ++i) {
read(x);
vec[x].push_back(i);
}
for(int i = 0; i <= n; ++i)
for(auto j : vec[i])
a[++ct] = mp(i, j);
for(int i = 1; i <= n; ++i) {
sum += a[i].fir;
if(sum == i * (i-1) / 2) {
if(lst != i-1) {
int now = a[i].fir - a[lst+1].fir;
if(now > mx)
mx = now,
ansu = a[lst+1].sec,
ansv = a[i].sec;
}
lst = i;
}
}
printf("! %d %d\n", ansu, ansv);
return 0;
}
竞赛图有个经典结论,其强连通缩点后的DAG呈类似于链状, 前面的所有点向后面的所有点连边。网上能搜到很多证明,这里就不重复论述了。
可以发现,拓扑序在前的SCC的任意一节点的入度严格小于拓扑序在后的SCC的任意一节点入度。因为前面的SCC的点必定向后面的SCC的点连边。
所以所有节点按照入度和从小到大排序后,同一个SCC的节点一定是连续的。
引理一:若一个竞赛图按照入度从小到大排序,仅有 满足前 的入度和为 ,则这个竞赛图缩点后只有一个SCC。
原因很简单,如果有多个SCC,那么第一个SCC若以 结尾,一定满足入度和为 ,与仅有 时满足不符。
中的结论的必要性比较显然,在此不多赘述。
考虑 中提到的步骤,由引理一得,若第一个满足条件的为 ,则前 个节点在同一个SCC,因为前 个节点之间互相只有 条边,而入度也正好统计到了这么多边,所以可以看成引理一的情况。
现在已经求出第一个SCC了,如果我们找到的第二个满足条件的点在 。
由于满足必要性,所以此时考虑前 个节点时,要不然是两个 SCC,要不然后面的组成不了SCC。
设第一个SCC为集合 ,其大小为 。后面的点组成的集合为 ,其大小为 。
只考虑 ,则他们的入度和为 ,由于图为竞赛图,所以 中的每个点一定都与 中每个点相连,且这些有向边一定是朝向 中的点,这一部分的入度和为 。
总的入度和为 ,发现这个求和与前面两个求和的差值恰好为 。
也就是说, 内部的点的入度和为 ,由引理一可得 可组成一个SCC。
这是两个的情况,注意到对于 来说,仅使用到了 内部的入度和为 ,以及 中的每个点一定都与 中每个点相连,将 扩展为前 个SCC的点组成的集合同样满足这两条性质。
结论的充分性得证。
本文即使略去一些繁琐的,不必要的推导,仍显得篇幅略长。如有质疑或建议欢迎提出。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?