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;
}

浙公网安备 33010602011771号