【SDOI2019】—热闹的聚会与尴尬的聚会(图论)
实在不知道这个用了什么算法
由于第二个最大独立集是问题
考虑先尽量让最大
这个可以直接用堆维护一下当前度数最小
然后考虑这样一个暴力的做法
每次取当前度数最小的点,并把所有相邻的点删去
由于不可能取到度数大于的点(否则当前这个子图的就比第一问求出的大了)
所以每次最多删去个点
总共也就会取个点
于是肯定是满足条件的
#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ob==ib)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
#define poly vector<int>
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int N=10005;
vector<int> e[N];
int n,m,p,q;
int in[N],du[N],vis[N],del[N],stk[N],top;
priority_queue<pii,vector<pii>,greater<pii> > s;
char obuf[RLEN],*olen=obuf;
#define pc(x) (*(olen++)=(x))
inline void write(int x){
(x>=10)&&(write(x/10),1);
pc(x%10+'0');
}
inline void solve(){
n=read(),m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
in[u]++,in[v]++,e[u].pb(v),e[v].pb(u);
}
for(int i=1;i<=n;i++)du[i]=in[i],s.push(pii(in[i],i)),vis[i]=0;
while(!s.empty()){
int u=s.top().se;s.pop();
if(vis[u])continue;
p=du[u],vis[u]=1;top=0;
for(int &v:e[u])if(!vis[v]){
du[v]--,s.push(pii(du[v],v));
}
stk[++top]=u;
while(!s.empty()&&s.top().fi<=p){
int u=s.top().se;s.pop();
if(vis[u])continue;
vis[u]=1;stk[++top]=u;
for(int &v:e[u])if(!vis[v]){
du[v]--,s.push(pii(du[v],v));
}
}
}
write(top);pc(' ');while(s.size())s.pop();
for(int i=1;i<=top;i++)write(stk[i]),pc(' ');pc('\n');
top=0;q=n/(p+1);
for(int i=1;i<=n;i++)du[i]=in[i],s.push(pii(in[i],i)),vis[i]=0,del[i]=0;
while(!s.empty()){
int u=s.top().se;s.pop();
if(vis[u]||del[u])continue;
vis[u]=1;stk[++top]=u;if(top>=q)break;
for(int &v:e[u]){
del[v]=1;
for(int &x:e[v])if(!del[x]&&!vis[x]){
du[x]--,s.push(pii(du[x],x));
}
}
}
write(top),pc(' ');
for(int i=1;i<=top;i++)write(stk[i]),pc(' ');pc('\n');
for(int i=1;i<=n;i++)e[i].clear(),in[i]=0;
top=0;while(s.size())s.pop();
}
int main(){
int T=read();
while(T--)solve();
fwrite(obuf,1,olen-obuf,stdout);
}