Gym 101981I - Magic Potion - [最大流][2018-2019 ACM-ICPC Asia Nanjing Regional Contest Problem I]

題目連接:http://codeforces.com/gym/101981/attachmentsc++

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).ide

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

Examplesrest

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

standard output
4blog

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 10three

standard output
7ci

 

題意:get

有 $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\n",dinic.maxflow());
}
相關文章
相關標籤/搜索