[AGC067A] Big Clique Everywhere
Genius_Star · · 题解
或许更好的阅读体验。
思路:
显然是需要找到一个判定图合法的充要条件。
这个团的限制看起来不太好做,考虑取补图后,对于一个团在补图中是一个独立集。
于是问题转化为,对于任意
这是充要的,因为对于任何一个集合
但是边数是
时间复杂度为
完整代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define lowbit(x) (x) & (-(x))
#define popcnt(x) __builtin_popcount(x)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int N = 5e3 + 10, M = 1e6 + 10;
inline ll read(){
ll x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')
f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return x * f;
}
inline void write(ll x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
bool flag = 0;
int T, n, m;
int a[M], b[M];
bool col[N], vis[N];
bool vise[N][N];
inline void bfs(int s){
queue<int> q;
q.push(s);
vis[s] = 1;
col[s] = 0;
while(!q.empty()){
int u = q.front();
q.pop();
for(int v = 1; v <= n; ++v){
if(!vise[u][v])
continue;
if(vis[v]){
if(col[u] == col[v]){
flag = 1;
return ;
}
}
else{
col[v] = col[u] ^ 1;
vis[v] = 1;
q.push(v);
}
}
}
}
inline void solve(){
n = read(), m = read();
for(int i = 1; i <= m; ++i)
a[i] = read(), b[i] = read();
if(n > sqrt(4 * m) + 5){
puts("No");
return ;
}
flag = 0;
for(int i = 1; i <= n; ++i){
vis[i] = col[i] = 0;
for(int j = 1; j <= n; ++j)
vise[i][j] = (i != j);
}
for(int i = 1; i <= m; ++i)
vise[a[i]][b[i]] = vise[b[i]][a[i]] = 0;
for(int i = 1; i <= n; ++i){
if(vis[i])
continue;
bfs(i);
if(flag)
break;
}
if(flag){
puts("No");
return ;
}
puts("Yes");
}
int main(){
T = read();
while(T--)
solve();
return 0;
}