hdu 2295 DLX+二分

来源:互联网 发布:java事务例子 编辑:程序博客网 时间:2024/06/08 01:16

把城市看做列,把雷达看成是行。

那么就是要求最少的行覆盖所有的列,并且可以重复覆盖。所以就发现了DLX的重复覆盖的身影~

至于半径就是二分了~

代码如下:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <cstring>#include <math.h>#include <stdlib.h>using namespace std;const int maxnode = 55*55;const int MaxM = 60;const int MaxN = 60;int N,M,K;struct DLX{int n,m,size;int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];int H[MaxN],S[MaxM];int ands,ans[MaxN];void init(int _n,int _m){n = _n;m = _m;for(int i = 0;i <= m;i++){S[i] = 0;U[i] = D[i] = i;L[i] = i-1;R[i] = i+1;}R[m] = 0; L[0] = m;size = m;for(int i = 1;i <= n;i++)H[i] = -1;}void Link(int r,int c){++S[Col[++size]=c];Row[size] = r;D[size] = D[c];U[D[c]] = size;U[size] = c;D[c] = size;if(H[r] < 0)H[r] = L[size] = R[size] = size;else{R[size] = R[H[r]];L[R[H[r]]] = size;L[size] = H[r];R[H[r]] = size;}}void remove(int c){for(int i = D[c];i != c;i = D[i])L[R[i]] = L[i], R[L[i]] = R[i];}void resume(int c){for(int i = U[c];i != c;i = U[i])L[R[i]]=R[L[i]]=i;}bool v[maxnode];int f(){int ret = 0;for(int c = R[0];c != 0;c = R[c])v[c] = true;for(int c = R[0];c != 0;c = R[c])if(v[c]){ret++;v[c] = false;for(int i = D[c];i != c;i = D[i])for(int j = R[i];j != i;j = R[j])v[Col[j]] = false;}return ret;}bool Dance(int d){if(d + f() > K)return false;if(R[0] == 0)return d <= K;int c = R[0];for(int i = R[0];i != 0;i = R[i])if(S[i] < S[c])c = i;for(int i = D[c];i != c;i = D[i]){remove(i);for(int j = R[i];j != i;j = R[j])remove(j);if(Dance(d+1))return true;for(int j = L[i];j != i;j = L[j])resume(j);resume(i);}return false;}};DLX g;double eps=1e-8;struct Point{int x,y;void input(){scanf("%d%d",&x,&y);}}city[MaxM],sta[MaxN];int Dis[MaxN][MaxM];int dis(Point a,Point b){    int tempx=a.x-b.x;    int tempy=a.y-b.y;return tempx*tempx+tempy*tempy;}void cal_dis(){    int i,j;    for(i=1;i<=M;i++)    {        for(j=1;j<=N;j++)        {            Dis[i][j]=dis(sta[i],city[j]);        }    }}int main(){    //freopen("E.in","r",stdin);    //freopen("E.out","w",stdout);    int T;scanf("%d",&T);while(T--){scanf("%d%d%d",&N,&M,&K);for(int i = 1;i <=N;i++){city[i].input();}for(int i=1;i<=M;i++)        {            sta[i].input();        }        cal_dis();double l = 0.0, r = 2000.0;double ans = 0.0;while(l <= r&&(r-l)>eps){double mid = (l+r)/2;g.init(M,N);for(int i = 1;i <=M;i++)for(int j =1;j <=N;j++)if(Dis[i][j] <= mid*mid)g.Link(i,j);if(g.Dance(0)){r = mid-eps;ans = mid;}else l = mid+eps;}printf("%.6lf\n",ans);}    return 0;}


 

0 0