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;
}
posted @ 2023-05-24 16:48  wnsyou  阅读(30)  评论(0编辑  收藏  举报