zoukankan      html  css  js  c++  java
  • BZOJ 3993 [SDOI 2015] 星际战争 解题报告

    首先我们可以二分答案。

    假设当前二分出来的答案是 $Ans$ ,那么我们考虑用网络流检验:

    设武器为 $X$,第 $i$ 个武器的攻击力为 $B_i$;

    设机器人为 $Y$,第 $i$ 个机器人的装甲为 $A_i$;

    设 $Map[i][j]$ 表示第 $i$ 个机器人是否能攻击第 $j$ 号机器人。

    设源为 $S$,汇为 $T$,现在考虑连边:

    • $S ightarrow X_i$,容量为 $Ans * B_i$;
    • $Y_i ightarrow T$,容量为 $A_i$;
    • $forall (i,j),Map[i][j]=1:X_i ightarrow Y_j$,容量为 $infty$

    然后跑网络流,假设最大流为 $M$,那么看是否有:$M=sum A_i$。

    如果是,那么说明当前答案是满足的,更新上界,否则更新下界。

    毕竟 Gromah 太弱,只会做水题。

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <algorithm>
      6 using namespace std;
      7 typedef long double LD;
      8 #define N 50 + 5
      9 #define M 100000 + 5
     10 #define INF 1e9
     11 #define eps 1e-9
     12  
     13 int n, m, S, T, sum, tot;
     14 int A[N], B[N];
     15 int Head[N << 1], q[N << 1], Dfn[N << 1];
     16 bool Map[N][N];
     17 LD l = 0.0, r;
     18  
     19 struct Edge
     20 {
     21     int next, node;
     22     LD flow;
     23 }h[M];
     24  
     25 inline void addedge(int u, int v, LD fl)
     26 {
     27     h[++ tot].next = Head[u], Head[u] = tot;
     28     h[tot].node = v, h[tot].flow = fl;
     29     h[++ tot].next = Head[v], Head[v] = tot;
     30     h[tot].node = u, h[tot].flow = 0;
     31 }
     32  
     33 inline bool BFS()
     34 {
     35     for (int i = S; i <= T; i ++)
     36         Dfn[i] = 0;
     37     int l = 1, r = 1;
     38     q[1] = S, Dfn[S] = 1;
     39     while (l <= r)
     40     {
     41         int z = q[l ++];
     42         for (int i = Head[z]; i; i = h[i].next)
     43         {
     44             int d = h[i].node;
     45             LD p = h[i].flow;
     46             if (p < eps || Dfn[d]) continue ;
     47             Dfn[d] = Dfn[z] + 1;
     48             q[++ r] = d;
     49             if (d == T) return 1;
     50         }
     51     }
     52     return 0;
     53 }
     54  
     55 inline LD dinic(int z, LD inflow)
     56 {
     57     if (z == T || inflow < eps) return inflow;
     58     LD ret = inflow, flow;
     59     for (int i = Head[z]; i; i = h[i].next)
     60     {
     61         int d = h[i].node;
     62         LD p = h[i].flow;
     63         if (Dfn[d] != Dfn[z] + 1) continue ;
     64         flow = dinic(d, min(p, ret));
     65         ret -= flow;
     66         h[i].flow -= flow, h[i ^ 1].flow += flow;
     67         if (ret < eps) return inflow;
     68     }
     69     if (fabs(inflow - ret) < eps) Dfn[z] = -1;
     70     return inflow - ret;
     71 }
     72  
     73 inline bool Judge(LD k)
     74 {
     75     tot = 1;
     76     for (int i = S; i <= T; i ++)
     77         Head[i] = 0;
     78     for (int i = 1; i <= m; i ++)
     79         addedge(S, i, k * B[i]);
     80     for (int i = 1; i <= n; i ++)
     81         addedge(i + m, T, A[i]);
     82     for (int i = 1; i <= m; i ++)
     83         for (int j = 1; j <= n; j ++)
     84             if (Map[i][j]) addedge(i, j + m, INF);
     85     LD res = 0.0;
     86     while (BFS())
     87         res += dinic(S, INF);  
     88     return fabs(res - sum) < eps;
     89 }
     90  
     91 int main()
     92 {
     93     #ifndef ONLINE_JUDGE
     94         freopen("3993.in", "r", stdin);
     95         freopen("3993.out", "w", stdout);
     96     #endif
     97      
     98     scanf("%d%d", &n, &m);
     99     S = 0, T = n + m + 1;
    100     for (int i = 1; i <= n; i ++)
    101     {
    102         scanf("%d", A + i);
    103         r += A[i];
    104         sum += A[i];
    105     }
    106     for (int i = 1; i <= m; i ++)
    107         scanf("%d", B + i);
    108     for (int i = 1; i <= m; i ++)
    109         for (int j = 1; j <= n; j ++)
    110             scanf("%d", Map[i] + j);
    111     while (l + 1e-4 < r)
    112     {
    113         LD mid = (l + r) / 2;
    114         if (Judge(mid)) r = mid;
    115             else l = mid;
    116     }
    117     printf("%.4lf
    ", (double) l);
    118      
    119     #ifndef ONLINE_JUDGE
    120         fclose(stdin);
    121         fclose(stdout);
    122     #endif
    123     return 0;
    124 }
    3993_Gromah
  • 相关阅读:
    STM32F407 窗口看门狗 个人笔记
    Hadoop技巧系列索引
    从零自学Hadoop系列索引
    从零自学Hadoop(25):Impala相关操作下
    从零自学Hadoop(24):Impala相关操作上
    从零自学Hadoop(23):Impala介绍及安装
    Hadoop技巧(04):简易处理solr date 时区问题
    从零自学Hadoop(22):HBase协处理器
    从零自学Hadoop(21):HBase数据模型相关操作下
    从零自学Hadoop(20):HBase数据模型相关操作上
  • 原文地址:https://www.cnblogs.com/gromah/p/4430214.html
Copyright © 2011-2022 走看看