abc260_f Find 4-cycle 题解
Find 4-cycle
题意
有一个 \(s + t\) 个点 \(m\) 条边的简单无向图 \(G\)。点标号为 \(1 \cdots s + t\),边标号为 \(1 \cdots m\)。第 \(i\) 条边连接点 \(u_i\) 和 \(v_i\)。
如果 \(G\) 中包含一个大小为 \(4\) 的简单环,选择任意一个并按任意顺序输出环上的 \(4\) 个点。若不存在,输出 -1
。
数据范围
- \(2 \leqslant s \leqslant 3 \times 10^5, 2 \leqslant t \leqslant 3000\)。
- \(4 \leqslant m \leqslant \min(s \times t, 3 \times 10^5)\)。
- \(1 \leqslant u_i \leqslant s, s + 1 \leqslant v_i \leqslant s + t\)。
- \((u_i, v_i) \ne (u_j, v_j)(i \ne j)\)。
思路
这个数据范围就很有特征,\(s\) 很大,但 \(t\) 只有 \(3000\),这就是题目的提示。
既然 \(t^2\) 不会超时,那就往暴力一点的方向思考。
大小为 \(4\) 的环,必然是编号小于等于 \(s\) 的两个点和编号大于 \(s\) 的两个点。
枚举一个编号小于等于 \(s\) 的一个点 \(i\),选择两个与它相连的两个点(编号不同),如果这两个点都连向另外一个点,那么就找出了一个大小为 \(4\) 环,输出即可;否则标记这两个点都连向 \(i\)。
复杂度
- 时间:\(O(t^2 + s + m)\)。
- 空间:\(O(t^2 + m)\)。
Code
点击查看代码
#include <iostream>
#include <vector>
using namespace std;
const int N = 3e5 + 10;
int s, t, m, x, y, dp[3010][3010];
vector<int> v[N];
int main () {
ios::sync_with_stdio(0), cin.tie(0);
cin >> s >> t >> m;
for (int i = 1; i <= m; i++) {
cin >> x >> y;
v[x].push_back(y - s);
}
for (int i = 1; i <= s; i++) {
for (int j : v[i]) {
for (int k : v[i]) {
if (j != k) {
if (!dp[j][k]) {
dp[j][k] = i;
} else {
cout << i << ' ' << j + s << ' ' << k + s << ' ' << dp[j][k];
return 0;
}
}
}
}
}
cout << -1;
return 0;
}