zoukankan      html  css  js  c++  java
  • 10.23T2 二分+二分图(滑稽)

    #3847 轰炸

    描述

    Ljr 家里有矿。

    Ljr 有 M 套房子,你可以把它们分别看成 M 个点分布在直角坐标系中,Jerryzhong 非常 痛恨 ljr 这个青春富豪,于是他想要炸掉 ljr 的这 M 套房子。

    Jerryzhong 通过红石科技造了 N 台红石大炮,由于客户端不兼容,因此这 N 台大炮随 机分布在了这个直角坐标系中,每一台红石大炮的炮弹需要 t1 分钟发射,发射一枚炮弹之 后需要 t2 分钟重新装弹,炮弹飞行的速度为 v/分钟,他想知道最少需要多少时间才能轰炸 完 ljr 的 M 套房子,由于 Jerryzhong 忙着做(shui)题(tie),因此他将这件事情拜托给了你,你 能回答这个问题吗?

    你可以认为 N 台大炮一开始都已经填装好了弹药,且炮台和房子的距离为欧几里得距 离,所有炮弹无视地形限制,水平飞行,Jerryzhong 可以同时使用多个炮台,但每个炮台一 次只能发射一枚炮弹,炸掉房子不需要时间。

    由于 ljr 是个阔佬,所以他能够重新买 Q-1 次房,因此 Jerryzhong 会向你询问 Q 次炸完 房子的最少时间。

    输入

    第一行一个数 Q 表示询问次数。

    接下来一行 5 个整数 N,M,t1,t2,v 意义如题所述。

    接下来 N 行,每行两个数 x,y,表示 N 台红石炮的坐标。

    接下来 M 行,每行两个整数 x,y,表示 ljr 的 M 套房子的坐标。

    输出

    共 Q 行,每行一个实数表示最少时间,精确到小数点后 6 位。

    样例输入[复制]
    1
    3 3 30 20 1
    50 50
    0 1000
    1000 0
    0 0
    0 50
    50 0
    样例输出[复制]
    180.000000
    提示

    numQ N M 其他

    1 =1 ≤3 ≤2 无

    2 =1 ≤6 ≤5 无

    3 =1 ≤10 ≤10 v=1

    4 =1 ≤10 ≤10 t2=0

    5 =1 ≤10 ≤10 t1=0

    6 ≤5 ≤50 ≤50 t1=0,t2=0

    7 ≤5 ≤50 ≤50 v=1

    8 ≤10 ≤50 ≤50 无

    9 ≤15 ≤50 ≤50 无

    10 ≤15 ≤50 ≤50 无

    标签
    ZYH
     
     
     
     
     
    拆出m个点代表第i次攻击,然后二分时间,如果小于mid的两点连起来,看是否构成m组匹配就可以了
    当然这里我加了一点优化,直接实数二分是要炸掉的
    我们可以知道这个答案肯定是某一个炮弹打中的时间点,所以我们可以把所有的时间点给求出来然后排序,在上面二分就很方便了
    code:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iomanip>
     6 #include<algorithm>
     7 #define N 105
     8 using namespace std;
     9 long long n,m;
    10 double v,t2,t1;
    11 double eps=1e-9;
    12 long long matching[N],vis[N],g[10005][100],paox[N],paoy[N],fangx[N],fangy[N];
    13 double dis[20000][100],Tim[125005];
    14 int tot;
    15 bool match(long long u) {
    16     for(long long i=1; i<=m; i++) {
    17         if(vis[i]||!g[u][i])continue;
    18         vis[i]=1;
    19         if(!matching[i]||match(matching[i])) {
    20             matching[i]=u;
    21             return true;
    22         }
    23     }
    24     return false;
    25 }
    26 long long hun() {
    27     long long ans=0;
    28     for(long long i=1; i<=n*m; i++) {
    29         memset(vis,0,sizeof vis);
    30         if(match(i))ans++;
    31     }
    32     return ans;
    33 }
    34 double sq(double x) {
    35     return x*x;
    36 }
    37 double getdis(long long i,long long j) {
    38     return sqrt(sq(paox[i]-fangx[j])+sq(paoy[i]-fangy[j]));
    39 }
    40 bool check(double mid) {
    41     memset(g,0,sizeof g);
    42     for(long long i=1; i<=m; i++) { //拆点
    43         for(long long j=1; j<=n; j++) { //
    44             for(long long k=1; k<=m; k++) {
    45                 if(dis[(j-1)*m+i][k]-eps<=mid) {
    46                     g[(j-1)*m+i][k]=1;
    47                 }
    48             }
    49         }
    50     }
    51     if(hun()==m)return true;
    52     return false;
    53 }
    54 int main() {
    55     long long Q;
    56     cin>>Q;
    57     while(Q--) {
    58         tot=0;
    59         cin>>n>>m>>t1>>t2>>v;
    60         for(long long i=1; i<=n; i++)cin>>paox[i]>>paoy[i];
    61         for(long long i=1; i<=m; i++)cin>>fangx[i]>>fangy[i];
    62         
    63         double ans;
    64         for(long long i=1; i<=m; i++) { //拆点
    65             for(long long j=1; j<=n; j++) { //
    66                 for(long long k=1; k<=m; k++) {
    67                     dis[(j-1)*m+i][k]=getdis(j,k)/v+(t2+t1)*i-t2;
    68                     Tim[++tot]=dis[(j-1)*m+i][k];
    69                 }
    70             }
    71         }
    72         sort(Tim+1,Tim+1+tot);int l=1,r=tot;
    73 //        for(int i=1;i<=tot;i++)cout<<Tim[i]<<" ";cout<<"
    ";
    74 //        cout<<check(Tim[6])<<" sss
    ";
    75 //        for(int i=1;i<=tot;i++){
    76 //            memset(matching,0,sizeof matching);
    77 //            cout<<"i="<<i<<" Check="<<check(Tim[i])<<"
    ";
    78 //        }
    79         while(l<=r) {
    80             memset(matching,0,sizeof matching);
    81             int mid=(l+r)/2;
    82             if(check(Tim[mid]))r=mid-1,ans=Tim[mid];
    83             else l=mid+1;
    84         }
    85         cout<<fixed<<setprecision(6)<<ans<<'
    ';
    86     }
    87     return 0;
    88 }

    over

  • 相关阅读:
    PS软件之,快速的修改图片你的尺寸
    想的太多,做的太少
    Java-Junit 的Hello world
    Java-hibernate的映射文件
    工作思路
    Spring入门Hello World
    PHP 进制问题
    Java-hibernate的Hello World
    PHP获得header头进行分析
    动软模板使用教程
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9838298.html
Copyright © 2011-2022 走看看