【二分答案】【最大流】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 double db;
queue<int>q;
int n,m,a[N],b[N],sumv;
bool can[N][N];
int v[2*N*(N+1)],en,first[N*2+3],next[2*N*(N+1)];
db cap[2*N*(N+1)];
void AddEdge(int U,int V,db W)
{
    v[en]=V; cap[en]=W; next[en]=first[U]; first[U]=en++;
    v[en]=U; cap[en]=0; next[en]=first[V]; first[V]=en++;
}
int S,T,nn;
int d[N*2+3],cur[N*2+3];
bool bfs()
{
    memset(d,-1,sizeof(int)*(nn+1));
    d[S]=0;
    q.push(S);
    while(!q.empty())
      {
        int U=q.front(); q.pop();
        for(int i=first[U];i!=-1;i=next[i])
          if(d[v[i]]==-1&&cap[i]>EPS)
            {
              d[v[i]]=d[U]+1;
              q.push(v[i]);
            }
      }
    return d[T]!=-1;
}
db dfs(int U,db a)
{
    if(U==T||a<=EPS)
      return a;
    db Flow=0.0,f;
    for(int &i=cur[U];i!=-1;i=next[i])
      if(d[v[i]]==d[U]+1&&(f=dfs(v[i],min(a,cap[i])))>EPS)
        {
          cap[i]-=f;
          cap[i^1]+=f;
          Flow+=f;
          a-=f;
          if(a<=EPS)
            break;
        }
    if(Flow<=EPS) d[U]=-1;
    return Flow;
}
db MaxFlow()
{
    db Flow=0.0,tmp;
    while(bfs())
      {
        memcpy(cur,first,sizeof(int)*(nn+1));
        while((tmp=dfs(S,INF))>EPS) Flow+=tmp;
      }
    return Flow;
}
bool check(db Lim)
{
    memset(first,-1,sizeof(int)*(nn+1));
    en=0;
    for(int i=1;i<=m;++i)
      AddEdge(S,1+i,Lim*(db)b[i]);
    for(int i=1;i<=n;++i)
      AddEdge(1+m+i,T,(db)a[i]);
    for(int i=1;i<=m;++i)
      for(int j=1;j<=n;++j)
        if(can[i][j])
          AddEdge(1+i,1+m+j,INF);
    return fabs(MaxFlow()-(db)sumv)<=EPS?1:0;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
      {
        scanf("%d",&a[i]);
        sumv+=a[i];
      }
    for(int i=1;i<=m;++i) scanf("%d",&b[i]);
    for(int i=1;i<=m;++i)
      for(int j=1;j<=n;++j)
        scanf("%d",&can[i][j]);
    S=1; T=nn=m+n+2;
    db l=0.0,r=5000000.0;
    while(r-l>EPS)
      {
        db mid=(l+r)/2.0;
        if(check(mid))
          r=mid-EPS;
        else
          l=mid+EPS;
      }
    printf("%lf\n",l);
    return 0;
}
时间: 2024-10-05 00:57:42

【二分答案】【最大流】bzoj3993 [Sdoi2015]星际战争的相关文章

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 ******************************************************

BZOJ3993 [SDOI2015]星际战争 【二分 + 网络流】

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

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

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

【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或者以下时,这个巨型机器

luogu P3324 [SDOI2015]星际战争

二次联通门 : luogu P3324 [SDOI2015]星际战争 /* luogu P3324 [SDOI2015]星际战争 之前总是TLE 结果改了改Max的值就过了... 最大流 二分时间 源点与武器连边 装甲与汇点连边 武器再与装甲连边 把 时间 * 攻击作为边权,跑最大流 判断最后的流是否大于装甲的总和 */ #include <algorithm> #include <iostream> #include <cstring> #include <cs

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或者以下时,这个巨型

POJ 2112 Optimal Milking 二分答案+最大流

首先二分最长的边,然后删去所有比当前枚举的值长的边,算最大流,看是否能满足所有的牛都能找到挤奶的地方 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include

BZOJ 3993 Sdoi2015 星际战争 二分答案+最大流

题目大意:有n个机器人和m个激光武器,每个武器有一个威力和能打的集合,同一时刻只能打一个机器人,问最少多久可以全灭 二分答案+网络流= = 注意二分上界 #include <cstdio> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define M 110 #define S 0 #define T (M-1) #define E

BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连一条流量为k的边.两个人若互相喜欢则点1之间连边,不喜欢则点2之间连边 对于每个要验证的x值 将每个人的点1向源或汇连一条流量为x的边 然后二分答案跑最大流就可以 #include<cstdio> #include<cstring> #include<iostream> #