LOJ #3113. 「SDOI2019」热闹的聚会与尴尬的聚会 贪心+随机化
我不明白这道题第二问到底在说啥......
第一问比较简单,直接用 set 来贪心就行了.
然后我感觉第二问就是求一个最大独立集就行.
套路:都 0202 年了,看到最优化就要上随机化呀!!
code:
#include <bits/stdc++.h> #define N 10008 #define M 100008 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; int n,m,tot; int hd[N],to[M<<1],nex[M<<1],edges; int du[N],ori[N],del[N],vis[N],q[N],arr[N],in[N],brr[N]; inline void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } inline void clr_graph() { for(int i=0;i<=n;++i) hd[i]=0; for(int i=0;i<=edges;++i) to[i]=nex[i]=0; edges=0; } struct node { int u,deg; node(int u=0,int deg=0):u(u),deg(deg){} bool operator<(const node b) const { return deg==b.deg?u<b.u:deg<b.deg; } }; set<node>se; set<node>::iterator it; void dfs(int x) { vis[x]=1,q[++tot]=x; for(int i=hd[x];i;i=nex[i]) { int y=to[i]; if(vis[y]||del[y]) continue; dfs(y); } } inline int solve_1() { scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) { int x,y; scanf("%d%d",&x,&y),add(x,y),add(y,x); ++du[x],++du[y]; ++ori[x],++ori[y]; } for(int i=1;i<=n;++i) { se.insert(node(i,du[i])); } int ans=0,id=0; for(int i=1;i<=n;++i) { it=se.begin(); int u=(*it).u; if(du[u]>ans) ans=du[u],id=u; for(int j=hd[u];j;j=nex[j]) { int y=to[j]; if(del[y]) continue; se.erase(node(y,du[y])); --du[y]; se.insert(node(y,du[y])); } se.erase(node(u,du[u])),del[u]=1; } for(int i=1;i<=n;++i) del[i]=0; se.clear(); for(int i=1;i<=n;++i) du[i]=ori[i]; for(int i=1;i<=n;++i) se.insert(node(i,du[i])); for(int i=1;i<=n;++i) { it=se.begin(); int u=(*it).u; if(u==id) break; for(int j=hd[u];j;j=nex[j]) { int y=to[j]; if(del[y]) continue; se.erase(node(y,du[y])); --du[y]; se.insert(node(y,du[y])); } se.erase(node(u,du[u])),del[u]=1; } dfs(id); printf("%d ",tot); for(int i=1;i<=tot;++i) printf("%d ",q[i]); printf("\n"); tot=0; return ans; // 求出最佳解 } void solve_2(int p) { for(int i=1;i<=n;++i) arr[i]=i; int ans=0; for(int T=1;T<=10;++T) { random_shuffle(arr+1,arr+1+n); int size=0; for(int j=1;j<=n;++j) { int u=arr[j],flag=0; for(int k=hd[u];k;k=nex[k]) { int y=to[k]; if(in[y]==T) { flag=1; break; } } if(!flag) in[u]=T,++size; } if(size>ans) { ans=size; for(int i=1;i<=n;++i) brr[i]=arr[i]; } } printf("%d ",ans); for(int i=1;i<=n;++i) { int u=brr[i],flag=0; for(int j=hd[u];j;j=nex[j]) { int y=to[j]; if(in[y]==-1) { flag=1; break; } } if(!flag) in[u]=-1,printf("%d ",u); } } int main() { // setIO("input"); int T; scanf("%d",&T); while(T--) { int a=solve_1(); solve_2(a); for(int i=1;i<=n;++i) { in[i]=vis[i]=del[i]=ori[i]=du[i]=0; } clr_graph(); se.clear(); printf("\n"); } return 0; }