首页 > 其他分享 >[SDOI2015] 星际战争 题解

[SDOI2015] 星际战争 题解

时间:2024-05-05 14:55:37浏览次数:12  
标签:nxt 激光 int 题解 机器人 lv SDOI2015 ans 星际

假如将所有激光武器放在一边,所有机器人放在一边,激光武器向它可以伤害的机器人连边,再加超级源/汇点,这就是一个网络流问题。

考虑激光武器向机器人连的边容量无限,而机器人向超级汇点连的边容量为机器人的装甲值,而超级源点连向激光武器的边则是用时 \(\times\) 激光武器伤害。

发现假如答案为 \(ans\),则所有大于 \(ans\) 的情况都可以击溃所有机器人,而用时小于 \(ans\) 则一定无法击溃所有机器人,发现单调性,二分用时,看最大流是否等于机器人装甲值之和。

时间复杂度 \(O((n+m)^2nm\log maxans)\),其中 \(maxans\) 是答案上界。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=105,M=5505;
int n,m,s,t,h[N],d[N],c[N];
int k,to[M],nxt[M],e[N][N];
int w[M],a[N],b[N],sum;
void add(int x,int y,int z){
    w[++k]=z;to[k]=y;
    nxt[k]=h[x];h[x]=k;
    nxt[++k]=h[y];
    to[k]=x;h[y]=k;
}int bfs(){
    memset(c,-1,sizeof(c));
    queue<int>q;q.push(s);
    c[s]=0;d[s]=h[s];
    while(q.size()){
        int x=q.front();q.pop();
        for(int i=h[x];i;i=nxt[i]){
            int y=to[i],lv=w[i];
            if(lv>0&&c[y]==-1)
                d[y]=h[y],c[y]=c[x]+1,q.push(y);
        }
    }return (c[t]==-1)?0:1;
}int dfs(int x,int ans){
    if(x==t) return ans;
    int now=ans;
    for(int i=h[x];i&&now;i=nxt[i]){
        int y=to[i];int lv=w[i];
        if(lv<1||c[y]!=c[x]+1) continue;
        int zjy=dfs(y,min(now,lv));
        now-=zjy;w[i]-=zjy;w[i^1]+=zjy;
    }return ans-now;
}int dinic(){
    int ans=0;
    while(bfs())
        ans+=dfs(s,1e18);
    return ans;
}int check(int x){
    memset(h,0,sizeof(h));
    memset(to,0,sizeof(to));
    memset(w,0,sizeof(w));k=1;
    memset(nxt,0,sizeof(nxt));
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
            if(e[i][j]) add(i+n,j,1e18);
    for(int i=1;i<=n;i++)
        add(i,t,a[i]);
    for(int i=1;i<=m;i++)
        add(s,i+n,b[i]*x);
    if(dinic()==sum) return 1;
    return 0;
}signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m;t=n+m+1;
    for(int i=1;i<=n;i++)
        cin>>a[i],a[i]*=10000,sum+=a[i];
    for(int i=1;i<=m;i++) cin>>b[i];
    for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++)
            cin>>e[i][j];
    int l=0,r=200000000,ans;
    while(l<=r){
        int mid=(l+r)/2;
        if(check(mid))
            ans=mid,r=mid-1;
        else l=mid+1;
    }printf("%.6lf",ans/1e4);
    return 0;
}

标签:nxt,激光,int,题解,机器人,lv,SDOI2015,ans,星际
From: https://www.cnblogs.com/chang-an-22-lyh/p/18173498/sdoi2015-xingjizhanzheng_tj

相关文章

  • CF729B Spotlights 题解
    题目简述给出一个$n$行$m$列的$01$矩阵,定义每个点的价值为上下左右四个方向有$1$的方向数,求所有为$0$的点的价值和。题目分析我们首先可以考虑暴力,但是发现是不行的。于是我们考虑动态规划。设$dp_{i,j,0/1/2/3}$分别表示$(i,j)$这个点上方,左方,下方,右方是否有$......
  • [SCOI2007] 蜥蜴 题解
    发现实际上就是在求有多少只蜥蜴能逃出来。发现可以将柱子拆成入点和出点两部分,自己的出点向别人的入点连边,自己的入点向自己的出点连边。最后再加一个超级源点\(S\),连接所有有蜥蜴的柱子入点;再加一个超级汇点\(T\),连接所有能够跳出地图的柱子。我们猛然发现:这个问题不就是求......
  • 题解:AT_abc352_C [ABC352C] Standing On The Shoulders
    考场憋了很久,最后代码贼短……理想状态下,直接全排列解决问题。但是,\(1\len\le2\times10^5\),明显TLE,试都不用试的。咋优化呢?其实,前面的巨人只负责“打地基”,作为“塔尖儿”的巨人有且仅有1个。而前面地基随便排列,地基高度(他们的和)都不会变。所以,我们只需要枚举塔尖即......
  • 牛客小白月赛92 题解
    牛客小白月赛92题解A.获得木头签到\((x\times4)/2\times4=x\times8\)#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#definepbpush_back#defineall(u)u.begin(),u.end()#defineendl'\n'#definedebug(x......
  • 牛客 215E 黄魔法师 题解
    Description给出\(n,k\),求一个长度为\(n\)的数组\(a\),满足有恰好\(k\)对数对\((i,j)(1\leqi<j\leqn)\)满足\(a_i+a_j\)为完全平方数。如果不存在,输出\(-1\)。linkSolution显然如果\(k>\binom{n}{2}\)就一定无解。构造时会发现肯定要尽量弄成相同的......
  • 题解【[ABC155F] Perils in Parallel】(未完成)
    题目链接两个常规转化:灯的坐标与区间坐标都很大,不妨将其离散化,转化为\(1\simn\)的点与\(1\simn\)的操作区间。对于一段区间取反,可以理解为对一段区间异或\(1\),转化为在异或差分数组上操作,即差分数组\(diff_i=a_i\bigoplusa_{i-1}\),区间\([l,r]\)异或\(1\)转化为差......
  • 5月3日模拟赛题解(李时珍的皮肤衣 , 马大嘴的废话 , SSY的队列 , 清理牛棚 , 历史の研究)
    T1李时珍的皮肤衣发现是二进制进位,所以直接快速幂即可。#include<bits/stdc++.h>#defineint__int128inlineintread(){charch=getchar();intx=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'......
  • 题解:ssy的队列
    题目链接题目描述SSY是班集体育委员,总喜欢把班级同学排成各种奇怪的队形,现在班级里有\(N\)个身高互不相同的同学,请你求出这\(N\)个人的所有排列中任意两个相邻同学的身高差均不为给定整数\(M\)的倍数的排列总数。输入格式共三行:第一行为\(N\)第二行为\(N\)个不同的......
  • P10064 [SNOI2024] 公交线路 题解
    弱化版:CF1827EBusRoutes。对于\(n=2\)的情况可以判掉,剩下的情况取一个度数大于一的点作为根。首先发现如果叶子间满足条件,那么整棵树也满足条件。考虑叶子间什么时候满足条件,记点\(x\)通过最多一条路径可以到达的所有点的集合为\(S_x\),则需满足\(\forallx,y\in\mathbf......
  • [国家集训队] 矩阵乘法 题解
    发现实际上就是二维静态区间最大值,可以用整体二分维护。时间复杂度\(O((q+n^2)\log\max(a_{i,j})\logn^2)\)。#include<bits/stdc++.h>#definelllonglongusingnamespacestd;constintW=310005;constintQ=6e4+5;intn,q,w,ans[Q];intc[505][505],m;voidadd(i......