【SDOI2019】—热闹的聚会与尴尬的聚会(图论)

传送门

实在不知道这个用了什么算法

由于第二个qq最大独立集是npcnpc问题
考虑先尽量让pp最大
这个可以直接用堆维护一下当前度数最小

然后考虑这样一个暴力的做法
每次取当前度数最小的点,并把所有相邻的点删去

由于不可能取到度数大于pp的点(否则当前这个子图的pp就比第一问求出的大了)
所以每次最多删去pp个点
总共也就会取np+1lceilfrac n {p+1} ceil个点
于是肯定是满足条件的

#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('
');
	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('
');
	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);
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328505.html