HDU 2295(裸DLX要超时,需要剪枝)

本文介绍了一种基于回溯算法的雷达覆盖优化方案。通过构建图模型来解决雷达站点如何覆盖尽可能多的城市节点的问题,并利用算法X求解精确覆盖问题。算法通过不断调整雷达的有效覆盖范围,寻找最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

多了Judge()要是depth+judge()都大于count就直接返回false;

 

#include <iostream>

#include <cmath>

#include <stdio.h>

using namespace std;

 

const int N=100;

struct node{

int L,R,D,U,col;

}dia[N*N];

double map[N][N];

int Size[N];

 

pair<double,double>city[N],Radar[N];

 

int n,m,count;

void makegraph(double mid)

{

int i,j,now,pre,RP;

//////初始化头指针///////////

for(i=0;i<=n;i++)

{

dia[i].col=i;

dia[i].D=dia[i].U=i;

dia[i].L=i-1;

dia[i].R=i+1;

Size[i] = 0;

}

dia[0].L=n;dia[n].R=0;

now=n+1;

for(i=1;i<=m;i++)

{

RP=pre=now;//RP行指针

for(j=1;j<=n;j++)

if(map[i][j]<mid){

dia[now].col = j;//属于第几列

Size[j] ++;

 

dia[now].U = dia[j].U;

dia[now].D = j;

dia[dia[j].U].D = now;

dia[j].U = now;

 

dia[now].L=pre;

dia[now].R=RP;

dia[pre].R = now;

dia[RP].L = now;

pre = now++;

}

}

}

 

void Cover(int c)

{

//dia[dia[c].R].L = dia[c].L;

//dia[dia[c].L].R = dia[c].R;

for(int i=dia[c].D;i!=c;i=dia[i].D)

{

dia[dia[i].L].R = dia[i].R;

dia[dia[i].R].L = dia[i].L;

Size[dia[i].col] --;

}

}

void Recover(int c)

{

for(int i=dia[c].U;i!= c;i=dia[i].U)

//for(int j=dia[i].L;j!=i;j=dia[j].L)

{

dia[dia[i].L].R = i;

dia[dia[i].R].L = i;

Size[dia[i].col] ++;

}

//dia[dia[c].R].L=c;

//dia[dia[c].L].R=c;

}

 

int judge()

{

    int hash[N]={0};

    int ans=0,i,j,k;

    for(i=dia[0].R;i;i=dia[i].R)

        if(!hash[i])

        {

            ans++;

            hash[i]=1;

            for(j=dia[i].D;j!=i;j=dia[j].D)

                for(k=dia[j].R;k!=j;k=dia[k].R)

                    hash[dia[k].col]=1;

        }

    return ans;

}

bool Algorithm_X(int depth)

{

int i,j;

if(depth+judge()>count) 

//if(depth>count)

return false;

if(dia[0].R == 0)

return true;

 

int mi=0xfffffff,c_pos;

for(i=dia[0].R;i!=0;i=dia[i].R)

if(mi>Size[i]){

mi = Size[i];

c_pos = i;

if(mi == 1) break;

}

//if(Size[c_pos] == 0) return false;

//Cover(c_pos);

for(i=dia[c_pos].D;i != c_pos; i=dia[i].D)

{

Cover(i);

for(j=dia[i].R;j != i; j=dia[j].R)

Cover(j);

if(Algorithm_X(depth+1))

return true;

for(j=dia[i].L;j!=i;j=dia[j].L)

Recover(j);

Recover(i);

}

//Recover(c_pos);

return false;

}

 

void Init(double &ma)

{

int i,j;

for(i=1;i<=m;i++)

for(j=1;j<=n;j++)

{

map[i][j] = sqrt( (city[j].first-Radar[i].first) *(city[j].first-Radar[i].first)

+ (city[j].second - Radar[i].second) *(city[j].second - Radar[i].second) );

ma = max(ma,map[i][j]);

}

}

 

void print(double mid)

{

for(int i=1;i<=n;i++)

{

for(int j=1;j<=m;j++)

if(map[i][j]<=mid)

{

printf("1 ");

}

else

printf("0 ");

printf("/n");

}

}

 

int main()

{

int i,j;

int T;

scanf("%d",&T);

while(T --)

{

// memset(Size,0,sizeof(Size)

scanf("%d%d%d",&n,&m,&count);

for(i=1;i<=n;i++)

scanf("%lf%lf",&city[i].first,&city[i].second);

for(i=1;i<=m;i++)

scanf("%lf%lf",&Radar[i].first,&Radar[i].second);

double ma=0;

Init(ma);

double low=0,high=ma+1,mid;

while(low+1e-8<=high)

{

mid = (low+high)/2;

//mid = 3;

// printf("mid = %lf/n",mid);

makegraph(mid);

// print(mid);

bool flag = true;

/*for(i=dia[0].R;i!=0;i=dia[i].R)

if(Size[i]==0){

flag = false;

break;

}*/

if(flag && Algorithm_X(0))

high=mid;

else

low = mid;

}

printf("%.6lf/n",low);

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值