您的位置:首页 > 其它

zzulioj 1730: 通信基站 (全排列&DFS)好题

2016-03-01 20:45 274 查看
//原文不让粘贴。。。文章链接:http://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1730

1730: 通信基站

Time Limit: 1 Sec  Memory Limit: 128 MB

Submit: 35  Solved: 12

SubmitStatusWeb Board

Description

 

Input

 

Output

 

Sample Input

2

2 1 1

0 0

4 4

3 100 1

0 0

1 1

500 500

Sample Output

2.00

201.41

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define INF 0x3f3f3f3f3f
#define ll long long
#define N 11
using namespace std;
double x
,y
;
double r
;
double sum;
int a
,b
;
int s
;
int n,c8,cr;
int ta,tb;
double dis(int a,int b)
{
return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
}
void dfs(int p)
{
int i,j;
if(p==ta+1)
{
double res=0;
for(i=1;i<=n;i++)
res+=r[i];//将所有城市都覆盖的半径的和
sum=min(res,sum);//取最小的半径和
return ;
}
for(j=1;j<=tb;j++)
{
double d=dis(b[j],a[p]);
double rr=r[j];
r[j]=max(r[j],d);
dfs(p+1);
r[j]=rr;
}
}
double solve(int cnt)//被覆盖但却没建基站的个数
{
int i,j;
double res=c8*cnt;//建基站的钱
ta=tb=0;
for(i=1;i<=n;i++)
{
if(s[i])
b[++tb]=i;
else
a[++ta]=i;
r[i]=0;
}
sum=0;//如果建n个基站sum的值(半径和)就为0
if(cnt!=n)
sum=INF;
dfs(1);
return res+sum*cr;
}
int main()
{
int t;
int i,j,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&c8,&cr);
for(i=1;i<=n;i++)
scanf("%lf%lf",&x[i],&y[i]);
double ans=INF;
for(i=1;i<=n;i++)//建基站的个数
{
memset(s,0,sizeof(s));
for(j=1;j<=i;j++)
s[j]=1;
while(1)
{
ans=min(ans,solve(i));
if(!prev_permutation(s+1,s+n+1))//判断是否进行了全排列
break;
}
}
printf("%.2lf\n",ans);
}
return 0;
}


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: