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