luogu P3324 [SDOI2015]星际战争

二次联通门 : luogu P3324 [SDOI2015]星际战争

/*
    luogu P3324 [SDOI2015]星际战争

    之前总是TLE
    结果改了改Max的值就过了...

    最大流

    二分时间
    源点与武器连边
    装甲与汇点连边
    武器再与装甲连边
    把 时间 * 攻击作为边权,跑最大流
    判断最后的流是否大于装甲的总和
*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>

#define Max 101
#define EPS 0.0001
#define INF 1e7

using namespace std;

void read (int &now)
{
    now = 0;
    char word = getchar ();
    while (word < ‘0‘ || word > ‘9‘)
        word = getchar ();
    while (word >= ‘0‘ && word <= ‘9‘)
    {
        now = now * 10 + word - ‘0‘;
        word = getchar ();
    }
}

int deep[Max << 2];

int N, M;
int S, T = (Max << 2) - 1;
int armor[Max];
int fight[Max];
int Sum;
int Total;
int map[Max][Max];

int Edge_Count;
int edge_list[Max << 2];

struct Edge
{
    int to;
    double flow;
    int next;
}edge[(Max * Max) << 1];

inline void AddEdge (int from, int to, double flow)
{
    Edge_Count++;
    edge[Edge_Count].to = to;
    edge[Edge_Count].next = edge_list[from];
    edge[Edge_Count].flow = flow;
    edge_list[from] = Edge_Count;
    Edge_Count++;
    edge[Edge_Count].to = from;
    edge[Edge_Count].flow = 0;
    edge[Edge_Count].next = edge_list[to];
    edge_list[to] = Edge_Count;
}

double min (double a, double b)
{
    return a < b ? a : b;
}

double Flowing (int now, double flow)
{
    if (now == T || flow == 0)
        return flow;
    double res = 0, pos;
    for (int i = edge_list[now]; i; i = edge[i].next)
    {
        if (deep[edge[i].to] != deep[now] + 1 || edge[i].flow <= 0)
            continue;
        pos = Flowing (edge[i].to, min (edge[i].flow, flow));
        if (pos > 0)
        {
            flow -= pos;
            res += pos;
            edge[i].flow -= pos;
            edge[i ^ 1].flow += pos;
            if (flow == 0)
                return res;
        }
    }
    if (res == 0)
        deep[now] = -1;
    return res;
}

bool Bfs ()
{
    memset (deep, -1, sizeof deep);
    queue <int> Queue;
    deep[S] = 0;
    Queue.push (S);
    int now;
    while (!Queue.empty ())
    {
        now = Queue.front ();
        Queue.pop ();
        for (int i = edge_list[now]; i; i = edge[i].next)
            if (deep[edge[i].to] < 0 && edge[i].flow > 0)
            {
                deep[edge[i].to] = deep[now] + 1;
                if (edge[i].to == T)
                    return true;
                Queue.push (edge[i].to);
            }
    }
    return false;
}

bool Check (double Time)
{
    double Answer = 0;
    Edge_Count = 1;
    memset (edge_list, 0, sizeof edge_list);
    for (int i = 1; i <= M; i++)
        AddEdge (S, i, fight[i] * Time);
    for (int i = 1; i <= N; i++)
        AddEdge (i + M, T, armor[i]);
    for (int i = 1; i <= M; i++)
        for (int j = 1; j <= N; j++)
            if (map[i][j])
                AddEdge (i, j + M, INF);
    while (Bfs ())
        Answer += Flowing (S, INF);
    return Answer >= (double)Sum - EPS;
}

int main (int argc, char *argv[])
{
    read (N);
    read (M);
    for (int i = 1; i <= N; i++)
    {
        read (armor[i]);
        Sum += armor[i];
    }
    for (int i = 1; i <= M; i++)
    {
        read (fight[i]);
        Total += fight[i];
    }
    for (int i = 1; i <= M; i++)
        for (int j = 1; j <= N; j++)
            read (map[i][j]);
    double l = (double)Sum / (double)Total, r = 10000.00;
    double Answer = 0;
    double Mid;
    while (l < r)
    {
        Mid = (l + r) / 2.0;
        if (Check (Mid))
        {
            r = Mid - EPS;
            Answer = Mid;
        }
        else
            l = Mid + EPS;
    }
    printf ("%lf", Answer);
    return 0;
}
时间: 2024-08-04 21:18:27

luogu P3324 [SDOI2015]星际战争的相关文章

P3324 [SDOI2015]星际战争

传送门:https://www.luogu.org/problemnew/show/P3324 首先瞅一眼数据范围,发现m, n都很小,所以就可以初步断定这是一道网络流的题. 因为题中说每一个武器只能攻击特定的机器人,所以可以想象成这把武器有一条指向该机器人的边,那流量是多少呢?这是不确定的,因为武器攻击机器人的策略是不知道的.不过有一点可以确定,就是在时间t内,这把武器造成的伤害一定是b[i] * t,如果把武器i和源点连一条边,那么这条边的容量就是b[i] * t. 在考虑每一个机器人的装甲

【BZOJ3993】[SDOI2015]星际战争 二分+最大流

[BZOJ3993][SDOI2015]星际战争 Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机器人就被摧毁了.X军团有M个激光武器,其中第i个激光武器每秒可以削减一个巨型机器人Bi的装甲值.激光武器的攻击是连续的.这种激光武器非常奇怪,一个激光武器只能攻击一些特定的敌人.Y军团看到自己的巨型机器人被X

3993: [SDOI2015]星际战争

3993: [SDOI2015]星际战争 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1244  Solved: 560[Submit][Status][Discuss] Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值减少到0或者以下时,这个巨型

【BZOJ 3993】 [SDOI2015]星际战争

3993: [SDOI2015]星际战争 Time Limit: 10 Sec Memory Limit: 128 MBSec Special Judge Submit: 180 Solved: 108 [Submit][Status][Discuss] Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机器

BZOJ 3993 [SDOI2015]星际战争

题解:二分+网络流判定. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<string> #include<cmath> #include<ctime> #include<algorithm> #include<map> #include<set> #include<q

BZOJ3993 [SDOI2015]星际战争

二分答案...然后最大流验证是否可行... 没了,好水啊QAQ 1 /************************************************************** 2 Problem: 3993 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:40 ms 7 Memory:1156 kb 8 ******************************************************

BZOJ 3993 [SDOI2015]星际战争 二分+最大流

题意: 有n个怪兽,m个武器,每个武器能打哪些怪兽的关系已给出,每个武器在1s内可以打多少血量已给出,每个怪兽有多少血量已给出. 求怪兽团灭的最小时间. 解析: 同样是一道答案存在单调性的题目. 所以我们可以考虑二分答案后,每一次重新构建一次图. 修改的地方其实就是原点到每个武器的流量(即二分的答案时间内该武器最多能打血)以及将上一次跑过的图复原. 最后判断最大流是否等于怪兽总血量即可. 注意浮点数相等判断. 代码: #include <queue> #include <cmath>

【二分答案】【最大流】bzoj3993 [Sdoi2015]星际战争

二分Time,S->炮[i]:Time*b[i] 炮[i]->机器人[i]:INF 机器人[i]->T:a[i]. 判断是否满流. #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; #define N 51 #define EPS 0.000001 #define INF 2147483647.0 typedef d

[SDOI2015]星际战争

Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1310  Solved: 578[Submit][Status][Discuss] Description 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战.在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机器人就被摧毁了.X军团有M个激光武器,其