zoukankan      html  css  js  c++  java
  • Gym 101981I

    题目链接:http://codeforces.com/gym/101981/attachments

    There are n heroes and m monsters living in an island. The monsters became very vicious these days,
    so the heroes decided to diminish the monsters in the island. However, the i-th hero can only kill one
    monster belonging to the set Mi. Joe, the strategist, has k bottles of magic potion, each of which can buff
    one hero’s power and let him be able to kill one more monster. Since the potion is very powerful, a hero
    can only take at most one bottle of potion.
    Please help Joe find out the maximum number of monsters that can be killed by the heroes if he uses the
    optimal strategy.

    Input
    The first line contains three integers n, m, k (1 ≤ n, m, k ≤ 500) — the number of heroes, the number of
    monsters and the number of bottles of potion.
    Each of the next n lines contains one integer ti, the size of Mi, and the following ti integers
    Mi,j (1 ≤ j ≤ ti), the indices (1-based) of monsters that can be killed by the i-th hero
    (1 ≤ ti ≤ m, 1 ≤ Mi,j ≤ m).

    Output
    Print the maximum number of monsters that can be killed by the heroes.

    Examples

    standard input
    3 5 2
    4 1 2 3 5
    2 2 5
    2 1 2

    standard output
    4

    standard input
    5 10 2
    2 3 10
    5 1 3 4 6 10
    5 3 4 6 8 9
    3 1 9 10
    5 1 3 6 7 10

    standard output
    7

    题意:

    有 $n$ 个勇士,$m$ 个怪物,现在告诉你每个勇士可以杀哪些怪物,每个勇士只能从中选择一只怪物将其杀死,

    而 $n$ 个勇士中最多可以有 $k$ 个勇士能够多杀一只怪物。

    求最多能杀死的怪物数目。

    题解:

    最大流。根据题目所给的数据,从勇士向怪物连边,流量上限均为 $1$。

    源点连到每个勇士一条边,流量上限均为 $1$。源点连到另一个虚拟节点,流量上限为 $k$,该虚拟节点连向每个勇士,流量上限均为 $1$。

    每个怪物连向汇点,流量上限均为 $1$。

    求出最大流即为答案。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=2*500+10;
    struct Edge{
        int u,v,c,f;
    };
    struct Dinic
    {
        int s,t; //源点汇点
        vector<Edge> E;
        vector<int> G[maxn];
        void init(int l,int r)
        {
            E.clear();
            for(int i=l;i<=r;i++) G[i].clear();
        }
        void addedge(int from,int to,int cap)
        {
            E.push_back((Edge){from,to,cap,0});
            E.push_back((Edge){to,from,0,0});
            G[from].push_back(E.size()-2);
            G[to].push_back(E.size()-1);
        }
        int dist[maxn],vis[maxn];
        queue<int> q;
        bool bfs() //在残量网络上构造分层图
        {
            memset(vis,0,sizeof(vis));
            while(!q.empty()) q.pop();
            q.push(s);
            dist[s]=0;
            vis[s]=1;
            while(!q.empty())
            {
                int now=q.front(); q.pop();
                for(int i=0;i<G[now].size();i++)
                {
                    Edge& e=E[G[now][i]]; int nxt=e.v;
                    if(!vis[nxt] && e.c>e.f)
                    {
                        dist[nxt]=dist[now]+1;
                        q.push(nxt);
                        vis[nxt]=1;
                    }
                }
            }
            return vis[t];
        }
        int dfs(int now,int flow)
        {
            if(now==t || flow==0) return flow;
            int rest=flow,k;
            for(int i=0;rest>0 && i<G[now].size();i++)
            {
                Edge &e=E[G[now][i]]; int nxt=e.v;
                if(e.c>e.f && dist[nxt]==dist[now]+1)
                {
                    k=dfs(nxt,min(rest,e.c-e.f));
                    if(!k) dist[nxt]=0; //剪枝,去掉增广完毕的点
                    e.f+=k; E[G[now][i]^1].f-=k;
                    rest-=k;
                }
            }
            return flow-rest;
        }
        int mf; //存储最大流
        int maxflow()
        {
            mf=0;
            int flow=0;
            while(bfs()) while(flow=dfs(s,INF)) mf+=flow;
            return mf;
        }
    }dinic;
    int n,m,k;
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        dinic.s=0, dinic.t=n+m+2;
        dinic.addedge(dinic.s,n+m+1,k);
        for(int i=1,t;i<=n;i++)
        {
            dinic.addedge(dinic.s,i,1);
            dinic.addedge(n+m+1,i,1);
            scanf("%d",&t);
            for(int j=1,k;j<=t;j++)
            {
                scanf("%d",&k);
                dinic.addedge(i,n+k,1);
            }
        }
        for(int i=1;i<=m;i++) {
            dinic.addedge(n+i,dinic.t,1);
        }
        printf("%d
    ",dinic.maxflow());
    }
  • 相关阅读:
    vue+axios拦截器和webapi中读取的实现
    vue+webapi+jwt做token验证时需要注意的一些问题
    vue中引用js文件的方法
    vue+elementui实现表单验证
    vue编程式路由参数的传递
    vue+elementUI实现侧边菜单栏的功能
    vue+webAPI中json相互转换的点滴记录,用于实现按分值的调查问卷功能
    axios中Post请求的两种区别
    vue使用全局变量来定义axios请求地址
    .net Core3.1 webapi前后端一起部署到同一网站遇到的问题
  • 原文地址:https://www.cnblogs.com/dilthey/p/9979696.html
Copyright © 2011-2022 走看看