zoukankan      html  css  js  c++  java
  • 洛谷P3324 [SDOI2015]星际战争 题解

    题目链接:

    https://www.luogu.org/problemnew/show/P3324

    分析:

    因为本题的时间较多,不能枚举,但发现有单调性,于是二分答案,二分使用的时间TT

    每个攻击装置造成的伤害总量已知,为TBiT*B_i,现在有了伤害总量、生命总量,如何判断在TT时间内,机器人是否被全部打死?

    源点S向所有攻击装置连边,流量为TBiT*B_i

    攻击装置向能攻击到的机器人连边,流量为INF

    所有机器人向汇点T连边,流量为AiA_i

    验证TT时间所有机器人都能被打死 当且仅当 上图的最大流=Ai= sum A_i(所有机器人生命值之和)

    代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #define maxn 110
    #define inf 0x7fffffffffffffffll
    using namespace std;
    int n,m,s,t,d[maxn];
    long long sum,ans,Sum_A;
    long long a[maxn];
    long long b[maxn];
    int mp[maxn][maxn];
    struct edge
    {
        int to,rev;
        long long val;
        edge (int _to,long long _val,int _rev)
        {
            to=_to;
            val=_val;
            rev=_rev;
        }
    };
    vector<edge> e[maxn];
    void add(int x,int y,long long val)
    {
        e[x].push_back(edge(y,val,e[y].size()));
        e[y].push_back(edge(x,0,e[x].size()-1));
    }
    bool bfs()
    {
        memset(d, -1, sizeof(d));
        queue<int> q;
        q.push(s);
        d[s]=0;
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0;i<e[x].size();i++)
            {
                int y=e[x][i].to;
                if(d[y]==-1 && e[x][i].val)
                {
                    q.push(y);
                    d[y]=d[x]+1;
                }
            }
        }
        if(d[t]==-1)
            return 0;
        else
            return 1;
    }
    long long dfs(int x,long long low) 
    {
        if(x==t||low==0)
            return low;
        long long totflow=0;
        for(int i=0;i<e[x].size();i++)
        {
            int y=e[x][i].to;
            int rev=e[x][i].rev;
            if(d[y]==d[x]+1&&e[x][i].val) 
            {
                long long a=dfs(y,min(low,e[x][i].val)); 
                e[x][i].val-=a;
                e[y][rev].val+=a;
                low-=a;
                totflow+=a;
                if(low==0) 
                    return totflow;
            }
        }
        if(low!=0) 
            d[x]=-1;
        return totflow;
    }
    bool pd(long long Time)
    {
        for(int i=0;i<maxn;i++)
            e[i].clear();
        sum=ans=0;
        s=0,t=n+m+1;
        for(int i=1;i<=m;i++)
            add(s,i,Time*b[i]);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                if(mp[i][j])
                    add(i,j+m,inf);
        for(int j=1;j<=n;j++)
            add(j+m,t,a[j]*10000);
        while(bfs())
        {
        	ans+=dfs(s,inf);
        }
        if(ans==Sum_A*10000)
            return 1;
        else
            return 0;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            Sum_A+=a[i];
        }
        for(int i=1;i<=m;i++)
            scanf("%lld",&b[i]);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&mp[i][j]);
        long long l=0,r=10000000000000ll;
        long long an=l;
        while(l<=r)
        {
            long long mid=(l+r)/2;
            if(pd(mid))
            {
                an=mid;
                r=mid-1;
            }
            else
                l=mid+1;
        }
        printf("%.6lf
    ",(double)an/(double)10000.0);
        return 0;
    }
    
  • 相关阅读:
    dijkstra (模板)
    LUOGU P2476 [SCOI2008]着色方案
    LUOGU P2344 奶牛抗议 (树状数组优化dp)
    LaTeX 公式大全
    LUOGU P1505 [国家集训队]旅游 (树链剖分+线段树)
    LUOGU P2416 泡芙 (缩点+树剖)
    LUGOU P1092 虫食算
    BZOJ 3090: Coci2009 [podjela] (树形背包)
    bzoj 4823 [Cqoi2017]老C的方块——网络流
    bzoj 3158 千钧一发——网络流
  • 原文地址:https://www.cnblogs.com/ShineEternal/p/10834226.html
Copyright © 2011-2022 走看看