BZOJ1525 : [POI2006]Zos

由于k很小,所以随机一组解的正确率有90%以上。

每次随机选取一个没被删除的点,然后将与其相邻的点都删去即可。

#include<cstdio>
#include<cstdlib>
const int N=1000010,BUF=54000100;
int T,n,i,k,m,x,y,ans,q[N],t,loc[N],del[N],have;
struct edge{int v;edge*nxt;}*g[N],pool[N*6],*cur=pool,*p;
char Buf[BUF],*buf=Buf;
inline void add(int x,int y){p=cur++;p->v=y;p->nxt=g[x];g[x]=p;}
inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
int main(){
  fread(Buf,1,BUF,stdin);read(n),read(k),read(m);
  while(m--)read(x),read(y),add(x,y),add(y,x);
  for(T=n>=100000?1:10;T;T--){
    for(have=0,t=n,i=1;i<=n;i++)q[i]=loc[i]=i,del[i]=0;
    while(t){
      y=q[x=std::rand()%t+1],loc[q[x]=q[t--]]=x,have++;
      for(p=g[y];p;p=p->nxt)if(!del[p->v])del[p->v]=1,x=loc[p->v],loc[q[x]=q[t--]]=x;
    }
    if(have>ans)ans=have;
  }
  if(ans<k)puts("NIE");else printf("%d",ans);
  return 0;
}

  

原文地址:https://www.cnblogs.com/clrs97/p/4596432.html