就是我们每次都把
d
e
g
r
e
e
(
a
)
<
k
degree(a)<k
degree(a)<k的点删除,如果最后还剩下点那就可以输出
1
1
1
输出2的解法:
就是我们每次都把
d
e
g
r
e
e
(
a
)
<
k
−
1
degree(a)<k-1
degree(a)<k−1的删除,如果访问到了
d
e
g
r
e
e
=
k
−
1
degree=k-1
degree=k−1的点,把那个
k
−
1
k-1
k−1个点
p
u
s
h
push
push进
v
e
c
t
o
r
vector
vector,然后
k
∗
k
∗
l
o
g
k
k*k*logk
k∗k∗logk进行判断!!
我们建图用
v
e
c
t
o
r
vector
vector进行建图,对每次点进行
s
o
r
t
sort
sort
因为图的边数才
1
e
5
1e5
1e5,那么完全图最大才
s
q
r
t
(
1
e
5
)
sqrt(1e5)
sqrt(1e5)复杂度完全可以接受
AC code
#include<bits/stdc++.h>#definemid((l + r)>>1)#defineLsonrt <<1, l , mid#defineRsonrt <<1|1, mid +1, r#definems(a,al)memset(a,al,sizeof(a))#definelog2(a)log(a)/log(2)#definelowbit(x)((-x)& x)#defineIOSstd::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)#defineINF0x3f3f3f3f#defineLLF0x3f3f3f3f3f3f3f3f#defineffirst#definessecond#defineendl'\n'
using namespace std;constint N =2e6+10, mod =1e9+9;constint maxn =500010;constlongdouble eps =1e-5;constint EPS =500*500;typedeflonglong ll;typedefunsignedlonglong ull;typedef pair<int,int> PII;typedef pair<ll,ll> PLL;typedef pair<double,double> PDD;
template<typename T>voidread(T &x){
x =0;char ch =getchar();ll f =1;while(!isdigit(ch)){if(ch =='-')f*=-1;ch=getchar();}while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;}
template<typename T, typename... Args>voidread(T &first, Args&... args){read(first);read(args...);}
vector<int> G[maxn], cilpue, res;int d[maxn], vis[maxn];int n, m, k;inline bool check(){// 找解法2for(int i =0; i < res.size();++ i)for(int j = i +1; j < res.size();++ j){int pos =lower_bound(G[res[i]].begin(),G[res[i]].end(),res[j])- G[res[i]].begin();if(pos == G[res[i]].size())return0;if(G[res[i]][pos]!= res[j])return0;}return1;}inlinevoidinit(){for(int i =0; i <= n;++ i) G[i].clear(), d[i]=0, vis[i]=0;
res.clear();
cilpue.clear();}intmain(){
IOS;int T;
cin >> T;while(T --){
cin >> n >> m >> k;init();for(int i =1; i <= m ;++ i){int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
d[u]++;
d[v]++;}for(int i =1; i <= n;++ i)sort(G[i].begin(),G[i].end());// 对链接的点排序
priority_queue<PII, vector<PII>, greater<PII>> q;// 用优先队列,重复插入不怕,毕竟会先访问到小的for(int i =1; i <= n;++ i) q.push({d[i],i});int is =0;while(!q.empty()){auto top = q.top();if(top.first >= k)break;
q.pop();if(vis[top.second])continue;
vis[top.second]=1;
bool flag =0;if(d[top.second]== k -1&&1ll* k *(k -1)<=2ll* m) flag =1, res.push_back(top.second);// 特判for(auto it : G[top.second]){if(vis[it])continue;if(flag) res.push_back(it);
d[it]--;
q.push({d[it],it});}if(flag &&check()){
is =1;// 找到方法二就退出去了break;}
res.clear();}if(!is){for(int i =1; i <= n;++ i)if(!vis[i])
cilpue.push_back(i);}if(is){
cout <<2<< endl;for(auto it : res)
cout << it <<" ";
cout << endl;}elseif(!cilpue.empty()){
cout <<1<<" "<< cilpue.size()<< endl;for(auto it : cilpue)
cout << it <<" ";
cout << endl;}else cout <<"-1\n";}}