• 牛客:动物森友会(网络流+二分答案)


    题意:

    链接:https://ac.nowcoder.com/acm/contest/5278/L
    来源:牛客网

    Compute 最近开始玩动物森友会了。
    这个游戏的时间与现实时间是同步的(一周有 7 天),而一些特定事件只会在一周的某些天解锁。
    我们假设有 n 个不同的事件,而每个事件都会给予不同的材料,并且每个事件只会在一周中的特定几天开放,在开放的时间内可以完成多次。但由于 Compute 要参加训练,他每天并没有多少时间玩游戏,所以他每天最多只能完成 e 次事件。
    现在 Compute 想做出一件非常稀有的道具——高达,并且他计算出了他收集齐所有材料需要完成每一种事件的次数。

    假设现在 Compute 从周一开始玩这个游戏,他最少需要经过几天(包括不玩游戏的日子)才能造出高达?

    题解:

    /*
     *动物森友会
     *题意:
     *一周有7天
     *有n个不同的事件
     *一个事件只会在一周中的特定几天开放
     *在开放的时间可以完成多次
     *每天最多完成e次
     *每件事情有一个目标次数
     *从周一开始玩,最少需要几天才能达到目标
     *题解:
     *最小费用最大流的想法
     *源点向所有事件连边,容量为目标次数
     *所有事件向一周的7天连边,如果这个事件在当天能做
     *容量为inf
     *一周中的所有天向汇点连边,容量为e*当天在天数中出现的次数
     *二分天数
     *天数上界是1e18
     */
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+100;
    const ll inf=1e18;
    struct node {
        int u,v,nxt;
        ll w;
    }edge[maxn*2];
    int head[maxn];
    int tot;
    void addedge (int u,int v,ll w) {
        edge[tot].u=u;
        edge[tot].v=v;
        edge[tot].w=w;
        edge[tot].nxt=head[u];
        head[u]=tot++;
        
        edge[tot].u=v;
        edge[tot].v=u;
        edge[tot].w=0;
        edge[tot].nxt=head[v];
        head[v]=tot++;
    } 
    
    int c[maxn];
    int is[maxn][7];//事件i在第j天是否开放 
    int n,e;
    
    ll dep[maxn];
    ll inq[maxn];
    ll cur[maxn];
    int wjm;
    ll maxflow=0;
    int s,t;
    bool bfs () {
        for (int i=0;i<=t;i++) {
            cur[i]=head[i];
            dep[i]=inf;
            inq[i]=0;
        }
        dep[s]=0;
        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int u=q.front();
            q.pop();
            inq[u]=0;
            for (int i=head[u];i!=-1;i=edge[i].nxt) {
                int v=edge[i].v;
                if (dep[v]>dep[u]+1&&edge[i].w) {
                    dep[v]=dep[u]+1;
                    if (inq[v]==0) {
                        q.push(v);
                        inq[v]=1;
                    } 
                }
            }
        }
        if (dep[t]!=inf) return 1;
        return 0;
    }
    ll dfs (ll u,ll flow) {
        ll increase=0;
        if (u==t) {
            wjm=1;
            maxflow+=flow;
            return flow;
        }
        ll used=0;
        for (int i=cur[u];i!=-1;i=edge[i].nxt) {
            cur[u]=i;
            int v=edge[i].v;
            if (edge[i].w&&dep[v]==dep[u]+1) {
                if (increase=dfs(v,min(flow-used,edge[i].w))) {
                    used+=increase;
                    edge[i].w-=increase;
                    edge[i^1].w+=increase;
                    if (used==flow) break;
                }
            }
        }
        return used;
    }
    ll Dinic () {
        maxflow=0;
        while (bfs()) {
            wjm=1;
            while (wjm==1) {
                wjm=0;
                dfs(s,inf);
            }
        }
        return maxflow;
    }
    
    
    
    ll check (ll mid) {
        //mid表示天数
        //0为源点
        //1~n为事件点
        //n+1~n+7表示天
        //n+8表示汇点
        for (int i=0;i<maxn;i++) head[i]=-1;
        tot=0;
        s=0;
        t=n+8;
        for (int i=1;i<=n;i++) addedge(s,i,c[i]);
        for (int i=1;i<=n;i++) {
            for (int j=1;j<=7;j++) {
                if (is[i][j]) {
                    addedge(i,j+n,inf);
                }
            }
        }
        for (int i=1;i<=7;i++) addedge(i+n,t,(mid/7+(mid%7>=i))*e);
        ll ans=Dinic();
        return ans;
    }
    
    int main () {
        scanf("%d%d",&n,&e);
        int sum=0;
        for (int i=1;i<=n;i++) {
            scanf("%d",c+i);
            sum+=c[i];
            int m;
            scanf("%d",&m);
            for (int j=1;j<=m;j++) {
                int x;
                scanf("%d",&x);
                is[i][x]=1;
            }
        }
        ll l=1,r=1e9;
        ll u=-1;
        while (l<=r) {
            ll mid=(l+r)>>1;
            if (check(mid)==sum) {
                u=mid;
                r=mid-1;
            }
            else {
                l=mid+1;
            }
        }
        printf("%lld
    ",u);
    }
  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters
    记一次odoo创建新的模块时,但是在odoo web界面找不到应用的案例
    python实现格式化输出9*9乘法表
    format和urlencode的使用对比
    python字典小知识
    01
    深浅拷贝再回顾
    DRF的路由生成类的使用
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13565887.html
Copyright © 2020-2023  润新知