10pts 求hack
查看原帖
10pts 求hack
378467
Windy_YY楼主2023/4/21 21:05
/*
 * orz qlr
 * 首先算出每一个连通块。
 * 然后对于每一个连通块bfs一遍,删除所有的叶子节点。
 * 然后考虑计算答案:
   * 首先连通块必须是二分图,否则无解。
   * 如果连通块的每一个点的度数都是2,那么有解。
   * 如果存在且仅存在两个三度点,并且至少存在两个和两个三度点同时相邻的二度点。
   * 否则无解。
*/

// Code by 0248.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <queue>
#include <cassert>

const int N = 2e5 + 10;
std::vector<int> z[N];
int deg[N], fa[N];
std::pair<int, int> edge[N];
int n, m;
int color[N];

int find(int x)
{
  return x == fa[x] ? x : fa[x] = find(fa[x]);
}

bool dfs(int i, int stc = 1)
{
  color[i] = stc;
  for (auto &j : z[i])
    if (color[j] == -1 && !dfs(j, stc ^ 1))
      return false;
    else if (color[j] != (stc ^ 1))
      return false;
  return true;
}

bool binary_graph()
{
  memset(color, -1, sizeof color);
  for (int i = 1; i <= n; i++)
    if (color[i] == -1 && !dfs(i))
      return false;
  return true;
}

int main()
{
  int T;
  std::cin >> T;
  while (T--)
  {
    std::cin >> n >> m;
    for (int i = 1; i <= n; i++)
      z[i].clear(), deg[i] = 0;
    for (int i = 0; i < m; i++)
    {
      int u, v;
      std::cin >> u >> v;
      z[u].push_back(v);
      z[v].push_back(u);
      deg[u]++, deg[v]++;
      edge[i] = {u, v};
    }
    for (int i = 1; i <= n; i++)
      fa[i] = i;
    for (int i = 0; i < m; i++)
    {
      int u = edge[i].first, v = edge[i].second;
      int ta = find(u), tb = find(v);
      if (ta != tb)
        fa[ta] = tb;
    }
    if (binary_graph())
    {
      std::queue<int> q;
      for (int i = 1; i <= n; i++)
        if (deg[i] == 1)
        {
          q.push(i);
          deg[i] = 0;
        }
      while (q.size())
      {
        int t = q.front();
        q.pop();
        for (auto &j : z[t])
          if (deg[j] == 1)
          {
            deg[j] = 0;
            q.push(j);
          }
      }
      int mi = 1e9, mx = 0;
      for (int i = 1; i <= n; i++)
        if (deg[i] != 0)
        {
          mi = std::min(mi, deg[i]);
          mx = std::max(mx, deg[i]);
        }
      if (mx == 0)
        std::cout << "YES\n";
      else if (mi == 2 && mx == 2)
        std::cout << "YES\n";
      else if (mi == 2 && mx == 3)
      {
        int cnt3 = 0;
        for (int i = 1; i <= n; i++)
          if (deg[i] == 3)
            cnt3++;
        if (cnt3 == 2)
        {
          int cnt2 = 0;
          for (int i = 1; i <= n; i++)
            if (deg[i] == 2)
              cnt2++;
          if (cnt2 < 2)
            std::cout << "NO\n";
          else
          {
            std::vector<int> deg3;
            for (int i = 1; i <= n; i++)
              if (deg[i] == 3)
                deg3.push_back(i);
            assert(deg3.size() == 2);
            int id31 = deg3[0], id32 = deg3[1];
            std::vector<int> g31, g32;
            for (auto &i : z[id31])
              if (deg[i] == 3)
                g31.push_back(i);
            for (auto &i : z[id32])
              if (deg[i] == 3)
                g32.push_back(i);
            if (g31.size() >= 1 && g32.size() >= 1)
            {
              std::set<int> g33;
              for (auto &i : g31)
                g33.insert(i);
              for (auto &i : g32)
                g33.insert(i);
              if (g33.size() >= 2)
                std::cout << "YES\n";
              else
                std::cout << "NO\n";
            }
            else
              std::cout << "NO\n";
          }
        }
        else
          std::cout << "NO\n";
      }
      else
        std::cout << "NO\n";
    }
    else
      std::cout << "NO\n";
  }
  return 0;
}
2023/4/21 21:05
加载中...