zoukankan      html  css  js  c++  java
  • hlg1481 Attack of the Giant n-pus【二分+二分图】

    Attack of the Giant n-pus
    Time Limit: 2000 MS Memory Limit: 65536 K
    Total Submit: 71(6 users) Total Accepted: 8(5 users) Rating:  Special Judge: No
    Description

    A pirate ship is being attacked by a giant n-pus(hint 1) . The n tentacles and the head of the creature

    have pierced the deck and are wreaking havoc on the ship. In an attempt to stop the creature

    from completely destroying the ship, the captain charges towards the head of the creature. Un-

    fortunately, he quickly gets knocked back by one of the tentacles. The captain realizes he cannot

    attack the head of the n-pus as long as it can move its tentacles freely.

    Luckily the captain is not alone on the ship. There are p (p ≥ n) pirates spread around on the

    deck, ready to follow the captain’s orders. So the captain comes up with the following plan. If

    each tentacle is attacked by one of the pirates, he can move freely towards the head of the creature

    and finish it off. To be safe, the captain will start moving only after each of the tentacles is being

    attacked by a pirate. When the captain reaches the head, he can instantly kill the creature. The

    captain wants to figure out which pirates to send to which tentacles, such that the creature can

    be killed as fast as possible. As this happens regularly to pirates, the captain wants you to write

    a program to solve this problem.

    Input

    The first line of the input contains a single number: the number of test cases to follow. Each test

    case has the following format:

    • One line with two integers n and p, satisfying 1 ≤ n ≤ p ≤ 100: the number of tentacles of

      the n-pus and the number of pirates (excluding the captain), respectively.

    • One line with three integers xc , yc and vc : the captain’s coordinates and speed, respectively.

    • p lines, each with three integers xi , yi and vi : the coordinates and speed, respectively, of

      each pirate.

    • One line with two integers xh and yh : the coordinates of the head of the n-pus.

    • n lines, each with two integers xj and yj : the coordinates of each tentacle.

    All coordinates satisfy 0 ≤ x, y ≤ 10, 000. All speeds satisfy 1 ≤ v ≤ 100.

    The captain, the pirates, the head and the tentacles are all considered to be point-like (i.e. they

    have no size). Their locations are all distinct.

    The captain and all pirates move to their target in a straight line at their given speed and are not

    hindered by anyone or anything.

    Output

    For every test case in the input, the output should contain one floating point number on a single

    line: the minimum time it takes for the captain to kill the n-pus. Your answer should have either

    an absolute or a relative error of at most 10^−6 .

    Sample Input

    3 3 
    2 0 1 
    0 0 2
    1 0 3
    3 0 4
    2 3
    0 1
    1 1
    4 1
    1 3
    0 0 1
    3 0 1
    4 0 1
    7 0 2
    0 1
    4 2
    3 3
    0 0 2
    2 0 3
    3 0 1
    4 0 2
    0 1
    3 1
    4 1
    5 1
    Sample Output
    3.500000000
    2.802775638
    1.500000000
    Hint

    1. An n-pus is like an octopus, but then with n tentacles.

    原始题目的输出需要Special Judge,为了方便,输出答案时请精确到小数点后9位。

    Source
    BAPC 2011 Preliminaries

    这个困扰我三天的题终于解开了啊

    好艰辛啊

    5555~~~

    大意:

    一群水手去攻击一只只爪子的章鱼

    告诉你每个水手的位置和前进的速度

    又告诉你每个章鱼爪子的位置

    告诉你章鱼头部的位置又告诉你船长的位置和速度

    船长只有在所有的爪子被水手控制的情况下才会去攻击章鱼的头部

    问最后船长攻击到章鱼头部的最短时间

    要求精度误差在0.000000001之内

    分析:

    二分枚举发动攻击的时间,如果在该时间内水手能够抵达一只爪子就建立一条边

    最后求得结果

    不得不去吐槽一下啊

    黄老师不加sj还要求那么高的精度

    简直就是丧心病狂啊

    开始的时候一直TLE

    然后发现一个可以大大提高时间的地方就是事先处理出每个水手到每只爪子的距离

    然后还是TLE啊啊啊

    然后看周洲的代码

    发现他是用手写的邻接表

    我想不能吧  这么丧心病狂

    vector应该比邻接表慢不了几倍的速度吧

    我就改成邻接表储存

    结果

    就a了

    瞬间石化

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <vector>
      6 using namespace std;
      7 
      8 const int maxn = 101;
      9 
     10 int n, p;
     11 
     12 struct Edge
     13 {
     14     int to,next;
     15 }e[10002];
     16 int head[maxn];
     17 int tot;
     18 void add(int s,int u)
     19 {
     20     e[tot].to = u;
     21     e[tot].next = head[s];
     22     head[s] = tot++;
     23 }
     24 
     25 double xi[maxn], yi[maxn], vi[maxn];
     26 double xj[maxn], yj[maxn];
     27 double dist[maxn][maxn];
     28 
     29 int vis[maxn], Link[maxn];
     30 
     31 bool Find(int u) {
     32     for(int i = head[u]; i; i = e[i].next) {
     33         int v = e[i].to;
     34         if(!vis[v]) {
     35             vis[v] = 1;
     36             if(Link[v] == -1 || Find(Link[v]) ) {
     37                 Link[v] = u;
     38                 return true;
     39             }
     40         }
     41     }
     42     return false;
     43 }
     44 
     45 bool Match() {
     46     memset(Link, -1, sizeof(Link));
     47     for(int i = 1; i <= n; i++) {
     48         memset(vis, 0, sizeof(vis));
     49         if(!Find(i) ) return false;
     50     }
     51     return true;
     52 }
     53 
     54 double Dist(double x1, double y1, double x2, double y2) {
     55     double xx = x1 - x2;
     56     double yy = y1 - y2;
     57     return sqrt(xx * xx + yy * yy );
     58 }
     59 
     60 bool check(double mid) {
     61     tot = 1; memset(head, 0, sizeof(head));
     62     for(int i = 1; i <= n; i++) {
     63         for(int j = 1; j <= p; j ++) {
     64             if(dist[i][j] < mid) {
     65                 add(i, j);
     66             }
     67         }
     68     }
     69     if(Match()) {
     70         return true;
     71     }
     72     return false;
     73 }
     74 
     75 const double wucha = 0.0000000001;
     76 
     77 int main() {
     78     double xc, yc, vc;
     79     double xh, yh;
     80     int t;
     81     //freopen("test.txt","r",stdin);
     82     scanf("%d",&t);
     83     while(t--) {
     84         scanf("%d %d",&n, &p);
     85         scanf("%lf %lf %lf", &xc, &yc, &vc);
     86         for(int i = 1;  i <= p; i++) {
     87             scanf("%lf %lf %lf", &xi[i], &yi[i], &vi[i]);
     88         }
     89         scanf("%lf %lf", &xh, &yh);
     90         for(int i = 1; i <= n; i++) {
     91             scanf("%lf %lf", &xj[i], &yj[i]);
     92         }
     93         double low = 0, high = 0;
     94         for(int i = 1;i <= n; i++) {
     95             for(int j = 1; j <= p; j++) {
     96                 dist[i][j] = Dist(xj[i], yj[i], xi[j], yi[j]) * 1.0 / vi[j];
     97                 if(dist[i][j] > high) high = dist[i][j];
     98             }
     99         }
    100         while(low < high) {
    101             double mid = (low + high) * 0.5;
    102             if(!check(mid)) {
    103                 low = mid + wucha;
    104             } else {
    105                 high = mid - wucha;
    106             }
    107         }
    108         double ans = high + wucha;
    109         ans += (Dist(xc, yc, xh, yh) / vc);
    110         printf("%.9lf
    ", ans);
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    【原创】C#初级教程学习笔记004-流程控制
    【原创】C#初级教程学习笔记002-进入C#编程
    kettle迁移简单案例
    Pycharm切换Git分支
    pycharm新文件增加默认注释
    pytest-mark标签装饰器
    python生成requirements.txt
    Cyber GIS
    mybatis之foreach用法_(搬运)
    Python 十进制、二进制、八进制、十六进制的转化
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/3980639.html
Copyright © 2011-2022 走看看