把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P5361 [SDOI2019]热闹的聚会与尴尬的聚会

题面传送门
感觉看到这个最大独立集就一脸不可做好吧。
但是题目里给的这个限制实在是好松啊,感觉啥啥都能过的亚子。
然后你发现其实第一问用个堆是可以求出最优解的,大概就是每次把最小度数的一个点删了,然后看剩下最小的度数是多大就好了。
然后你发现第二问冲个随机排列它过了
我们发现如果贪心地让最大独立集最大,那么度数之和一定大于\(n\),否则还可以加入更多地点。
而第一问地贪心策略保证了我们加入的点最多只有\(p\)个新删除的点。
所以再做一遍就好了,时间复杂度\(O(n\log n)\)
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define ll long long
#define db double
#define lb long db
#define N (10000+5)
#define M (220+5)
#define K (12+5)
#define mod 1000000007
#define Mod (mod-1)
#define eps (1e-9)
#define ull unsigned ll
#define it iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) (n*(x-1)+(y))
#define R(n) (rand()*rand()%(n)+1)
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
struct IO{
    static const int S=1<<21;
    char buf[S],*p1,*p2;int st[105],Top;
    ~IO(){clear();}
    inline void clear(){fwrite(buf,1,Top,stdout);Top=0;}
    inline void pc(const char c){Top==S&&(clear(),0);buf[Top++]=c;}
    inline char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    inline IO&operator >> (char&x){while(x=gc(),x==' '||x=='\n'||x=='\r');return *this;}
    template<typename T>inline IO&operator >> (T&x){
        x=0;bool f=0;char ch=gc();
        while(ch<'0'||ch>'9'){if(ch=='-') f^=1;ch=gc();}
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=gc();
        f?x=-x:0;return *this;
    }
    inline IO&operator << (const char c){pc(c);return *this;}
    template<typename T>inline IO&operator << (T x){
        if(x<0) pc('-'),x=-x;
        do{st[++st[0]]=x%10,x/=10;}while(x);
        while(st[0]) pc('0'+st[st[0]--]);return *this;
    }
}fin,fout;
using namespace std;vector<int> S[N];
int T,n,x,y,Fl[N],I1[N],I2[N],m,Ts[N],Th,Ans;
struct Ques{int w,id;bool operator <(const Ques &B)const{return w>B.w;};}Ns;priority_queue<Ques> Q;
I void Solve(){
	int i,j;fin>>n>>m;for(i=1;i<=n;i++) S[i].clear(),I1[i]=I2[i]=Fl[i]=0;
	while(m--) fin>>x>>y,S[x].PB(y),S[y].PB(x),I1[x]++,I1[y]++;Mc(I2,I1);
	Ans=-1e9;Th=0;for(i=1;i<=n;i++) Q.push((Ques){I1[i],i});while(!Q.empty()){
		Ns=Q.top();Q.pop();if(I1[Ns.id]^Ns.w) continue;Ans=max(Ans,Ns.w);for(int i:S[Ns.id]) I1[i]&&(I1[i]--,Q.push((Ques){I1[i],i}),I1[Ns.id]--);
	}
	Mc(I1,I2);for(i=1;i<=n;i++) Q.push((Ques){I1[i],i});while(!Q.empty()){
		Ns=Q.top();Q.pop();if(I1[Ns.id]^Ns.w) continue;if(Ans==Ns.w){Ts[Th=1]=Ns.id;while(!Q.empty()) Ns=Q.top(),Q.pop(),I1[Ns.id]==Ns.w&&(Ts[++Th]=Ns.id);break;}
		for(int i:S[Ns.id]) I1[i]&&(I1[i]--,Q.push((Ques){I1[i],i}),I1[Ns.id]--);
	}fout<<Th<<' ';for(i=1;i<=Th;i++) fout<<Ts[i]<<' ';fout<<'\n';
	Th=0;for(i=1;i<=n;i++) Q.push((Ques){I1[i],i});while(!Q.empty()){
		Ns=Q.top();Q.pop();if(Ns.w^I1[Ns.id]) continue;if(Fl[Ns.id]) continue;Fl[Ts[++Th]=Ns.id]=1;for(int i:S[Ns.id]){
			if(Fl[i]) continue;Fl[i]=1;for(int j:S[i]) I1[j]&&(I1[j]--,Q.push((Ques){I1[j],j}),I1[i]--,0); 
		}
	}fout<<Th<<' ';for(i=1;i<=Th;i++) fout<<Ts[i]<<' ';fout<<'\n';
}
int main(){
	freopen("1.in","r",stdin);freopen("1.out","w",stdout); 
	fin>>T;while(T--) Solve();
}
posted @ 2022-05-07 19:46  275307894a  阅读(23)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end