bzoj4080 Wf2014 Sensor Network 随机化

来源:互联网 发布:银行存款怎样划算知乎 编辑:程序博客网 时间:2024/06/05 14:33

题意:给你一个点集,让你选出最多的点同时保证任意两个点之间距离不能超过d。
一开始一看见n<=100以为直接暴力加入,然后每一次在已经加入的里面比较,结果WA了。。其实挺明显的,肯定不是最优的啊= =,要保证正确性只能2^100。。。
所以就懵逼了,题解是随机化一个序列以后贪心来,感觉整个人都不好了。。还有这种选学算法= =

#include<cstdio>#include<algorithm>#include<cstring>#include<bitset>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=105+5;int n,m;int d,w[N];bitset<N>ans,now;bool f[N][N],vis[N];struct node{    int x,y;}a[N];inline int getdis(node a,node b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}inline void Rand(){    fo(i,1,n)swap(w[i],w[rand()%n+1]);}inline void solve(){    memset(vis,0,sizeof(vis));    now.reset();    fo(i,1,n)    if (!vis[i])    {        now.set(w[i]);        fo(j,i+1,n)        if (!f[w[i]][w[j]])vis[j]=1;    }    if (now.count()>ans.count())ans=now;}int main(){    scanf("%d%d",&n,&d);    fo(i,1,n)    {        scanf("%d%d",&a[i].x,&a[i].y);        w[i]=i;    }    fo(i,1,n-1)    fo(j,i+1,n)    if (getdis(a[i],a[j])<=d*d)f[i][j]=f[j][i]=1;    fo(i,1,1000)Rand(),solve();    printf("%d\n",ans.count());    fo(i,1,n)if (ans[i])printf("%d ",i);}
原创粉丝点击