zoukankan      html  css  js  c++  java
  • bzoj 3993 星际战争

    3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战。在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai。当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机器人就被摧毁了。X军团有M个激光武器,其中第i个激光武器每秒可以削减一个巨型机器人Bi的装甲值。激光武器的攻击是连续的。这种激光武器非常奇怪,一个激光武器只能攻击一些特定的敌人。Y军团看到自己的巨型机器人被X军团一个一个消灭,他们急需下达更多的指令。为了这个目标,Y军团需要知道X军团最少需要用多长时间才能将Y军团的所有巨型机器人摧毁。但是他们不会计算这个问题,因此向你求助。

    Input

    第一行,两个整数,N、M。

    第二行,N个整数,A1、A2…AN。
    第三行,M个整数,B1、B2…BM。
    接下来的M行,每行N个整数,这些整数均为0或者1。这部分中的第i行的第j个整数为0表示第i个激光武器不可以攻击第j个巨型机器人,为1表示第i个激光武器可以攻击第j个巨型机器人。

    Output

     一行,一个实数,表示X军团要摧毁Y军团的所有巨型机器人最少需要的时间。输出结果与标准答案的绝对误差不超过10-3即视为正确。

    Sample Input

    2 2
    3 10
    4 6
    0 1
    1 1

    Sample Output

    1.300000

    Hint

     【样例说明1】

    战斗开始后的前0.5秒,激光武器1攻击2号巨型机器人,激光武器2攻击1号巨型机器人。1号巨型机器人被完全摧毁,2号巨型机器人还剩余8的装甲值;
    接下来的0.8秒,激光武器1、2同时攻击2号巨型机器人。2号巨型机器人被完全摧毁。
    对于全部的数据,1<=N, M<=50,1<=Ai<=105,1<=Bi<=1000,输入数据保证X军团一定能摧毁Y军团的所有巨型机器人

      二分时间,然后建图,激光武器和源点相连,容量为这个激光武器在这个时间内能够造成的伤害,机器人和汇点连边,容量为机器人的装甲值,激光武器和它能够攻击的目标连一条边,容量为无限大。

    Code

      1 /**
      2  * bzoj
      3  * Problem#3993
      4  * Accepted
      5  * Time:48ms
      6  * Memory:1688k
      7  */
      8 #include <iostream>
      9 #include <cstdio>
     10 #include <ctime>
     11 #include <cmath>
     12 #include <cctype>
     13 #include <cstring>
     14 #include <cstdlib>
     15 #include <fstream>
     16 #include <sstream>
     17 #include <algorithm>
     18 #include <map>
     19 #include <set>
     20 #include <stack>
     21 #include <queue>
     22 #include <vector>
     23 #include <stack>
     24 #ifndef WIN32
     25 #define Auto "%lld"
     26 #else
     27 #define Auto "%I64d"
     28 #endif
     29 using namespace std;
     30 typedef bool boolean;
     31 const signed int inf = (signed)((1u << 31) - 1);
     32 const double eps = 1e-6;
     33 #define smin(a, b) a = min(a, b)
     34 #define smax(a, b) a = max(a, b)
     35 #define max3(a, b, c) max(a, max(b, c))
     36 #define min3(a, b, c) min(a, min(b, c))
     37 template<typename T>
     38 inline boolean readInteger(T& u){
     39     char x;
     40     int aFlag = 1;
     41     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     42     if(x == -1) {
     43         ungetc(x, stdin);
     44         return false;
     45     }
     46     if(x == '-'){
     47         x = getchar();
     48         aFlag = -1;
     49     }
     50     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     51     ungetc(x, stdin);
     52     u *= aFlag;
     53     return true;
     54 }
     55 
     56 typedef class Edge {
     57     public:
     58         int end;
     59         int next;
     60         double flow;
     61         double cap;
     62         Edge(int end = 0, int next = -1, double flow = 0, double cap = 0):end(end), next(next), flow(flow), cap(cap) {    }
     63 }Edge;
     64 
     65 typedef class MapManager {
     66     public:
     67         int ce;
     68         vector<Edge> edge;
     69         int* h;
     70         
     71         MapManager():ce(0), h(NULL) {        }
     72         MapManager(int nodes):ce(0) {
     73             h = new int[(const int)(nodes + 1)];
     74             memset(h, -1, sizeof(int) * (nodes + 1));
     75         }
     76         
     77         inline void addEdge(int from, int end, double flow, double cap) {
     78             edge.push_back(Edge(end, h[from], flow, cap));
     79             h[from] = ce++;
     80         }
     81         
     82         inline void addDoubleEdge(int from, int end, double cap) {
     83             if(cap == 0)    return;
     84             addEdge(from, end, 0, cap);
     85             addEdge(end, from, cap, cap);
     86         }
     87         
     88         Edge& operator [] (int pos) {
     89             return edge[pos];
     90         }
     91         
     92         inline void clear() {
     93             delete[] h;
     94             edge.clear();
     95         }
     96 }MapManager;
     97 #define m_begin(g, i) (g).h[(i)]
     98 #define m_endpos -1
     99 
    100 inline boolean dcmp(double a, double b) {
    101     return fabs(a - b) < eps;
    102 }
    103 
    104 template<typename T>class Matrix{
    105     public:
    106         T *p;
    107         int lines;
    108         int rows;
    109         Matrix():p(NULL){    }
    110         Matrix(int rows, int lines):lines(lines), rows(rows){
    111             p = new T[(lines * rows)];
    112         }
    113         T* operator [](int pos){
    114             return (p + pos * lines);
    115         }
    116 };
    117 #define matset(m, i, s) memset((m).p, (i), (s) * (m).lines * (m).rows)
    118 
    119 int n, m;
    120 int *A, *B;
    121 int sA = 0;
    122 int s, t;
    123 Matrix<boolean> atable;
    124 
    125 inline void init() {
    126     readInteger(n);
    127     readInteger(m);
    128     A = new int[(const int)(n + 1)];
    129     B = new int[(const int)(m + 1)];
    130     atable = Matrix<boolean>(m + 1, n + 1);
    131     for(int i = 1; i <= n; i++)
    132         readInteger(A[i]), sA += A[i];
    133     for(int i = 1; i <= m; i++)
    134         readInteger(B[i]);
    135     for(int i = 1; i <= m; i++)
    136         for(int j = 1; j <= n; j++)
    137             readInteger(atable[i][j]);
    138     s = 0, t = n + m + 1;
    139 }
    140 
    141 MapManager g;
    142 inline void mkmap(double mid) {
    143     g = MapManager(n + m + 1);
    144     for(int i = 1; i <= m; i++)
    145         g.addDoubleEdge(s, i, B[i] * mid); 
    146     for(int i = 1; i <= n; i++)
    147         g.addDoubleEdge(i + m, t, A[i]); 
    148     for(int i = 1; i <= m; i++)
    149         for(int j = 1; j <= n; j++)
    150             if(atable[i][j])
    151                 g.addDoubleEdge(i, j + m, inf); 
    152 }
    153 
    154 int* dis;
    155 boolean* vis;
    156 queue<int> que;
    157 inline boolean bfs() {
    158     memset(vis, false, sizeof(boolean) * (t + 1));
    159     que.push(s);
    160     vis[s] = true;
    161     dis[s] = 0;
    162     while(!que.empty()) {
    163         int e = que.front();
    164         que.pop();
    165         for(int i = m_begin(g, e); i != m_endpos; i = g[i].next) {
    166             if(dcmp(g[i].cap, g[i].flow))    continue;
    167             int eu = g[i].end;
    168             if(vis[eu])    continue;
    169             vis[eu] = true;
    170             dis[eu] = dis[e] + 1;
    171             que.push(eu);
    172         }
    173     }
    174     return vis[t];
    175 }
    176 
    177 int *cur;
    178 inline double blockedflow(int node, double minf) {
    179     if((node == t) || (minf < eps))    return minf;
    180     double f, flow = 0;
    181     for(int& i = cur[node]; i != m_endpos; i = g[i].next) {
    182         int& eu = g[i].end;
    183         if(dis[eu] == (dis[node] + 1) && (f = blockedflow(eu, min(minf, g[i].cap - g[i].flow))) >= eps) {
    184             minf -= f;
    185             flow += f;
    186             g[i].flow += f;
    187             g[i ^ 1].flow -= f;
    188             if(minf < eps)    return flow;
    189         }
    190     }
    191     return flow;
    192 }
    193 
    194 inline void init_dinic() {
    195     vis = new boolean[(const int)(t + 1)];
    196     dis = new int[(const int)(t + 1)];
    197     cur = new int[(const int)(t + 1)];
    198 }
    199 
    200 inline boolean dinic(double mid) {
    201     mkmap(mid);
    202     double maxflow = 0.0;
    203     while(bfs()) {
    204         for(int i = s; i <= t; i++)
    205             cur[i] = m_begin(g, i);
    206         maxflow += blockedflow(s, inf);
    207     }
    208     g.clear();
    209     return dcmp(maxflow, sA);
    210 } 
    211 
    212 inline void solve() {
    213     init_dinic();
    214     double l = 0.0, r = sA;
    215     while(l + eps <= r) {
    216         double mid = (l + r) / 2;
    217         if(dinic(mid))    r = mid;
    218         else l = mid;
    219     }
    220     printf("%.6lf", r);
    221 }
    222 
    223 int main() {
    224     init();
    225     solve();
    226     return 0;
    227 }
  • 相关阅读:
    Task级别任务调度分析---源码级
    解决部署K8S集群时flannel无法下载问题
    安装kubernetes+docker集群,一篇文章搞定
    充值-实体类+查询
    充值-controller
    多对一的增删改查-list页面,add页面,update页面,tongji页面
    多对一的增删改查-dao层
    多对一的增删改查-sql语句
    多对一的增删改查-controller
    多对一的增删改查-service和impl
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7132779.html
Copyright © 2011-2022 走看看