2018icpc南京/gym101981 I Magic Potion

题意:

若干个勇士,每个勇士只能杀特定的怪物。每个勇士只能杀1个怪,但是有一些药,喝了药之后能再杀一个,每个勇士只能喝一瓶药。问你最多杀多少怪。

题解:

按照如下建图套网络流板即可。

网上有题解说套DinicT了,我们队套kuangbin的dinic过了,不得不说kuangbin的板质量真的好。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 1500 //最大点数
#define MAXM 1200010 //最大变数
const int INF=0x3f3f3f3f;
#define mem(a,b) memset(a,b,sizeof a)
#define dbg(x) cout<<#x<<"="<<x<<endl
struct Edge{
    int to,nxt,cap,flow;
}edge[MAXM];
int tol;
int head[MAXN];
void init()
{
    tol=0;
    mem(head,-1);
}
void add(int u,int v,int w,int rw=0)
{
    edge[tol].to=v,edge[tol].cap=w,edge[tol].flow=0,edge[tol].nxt=head[u],head[u]=tol++;
    edge[tol].to=u,edge[tol].cap=rw,edge[tol].flow=0,edge[tol].nxt=head[v],head[v]=tol++;
}
int Q[MAXN];
int dep[MAXN],cur[MAXN],sta[MAXN];
bool bfs(int s,int t,int n)
{
    int front=0,tail=0;
    mem(dep,-1);
    dep[s]=0;
    Q[tail++]=s;
    while(front<tail)
    {
        int u=Q[front++];
        for(int i=head[u];i!=-1;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(edge[i].cap>edge[i].flow&&dep[v]==-1)
            {
                dep[v]=dep[u]+1;
                if(v==t) return true;
                Q[tail++]=v;
            }
        }
    }
    return false;
}
int dinic(int s,int t,int n)
{
    int maxflow=0;
    while(bfs(s,t,n))
    {
        for(int i=0;i<n;++i) cur[i]=head[i];
        int u=s,tail=0;
        while(cur[s]!=-1)
        {
            if(u==t)
            {
                int tp=INF;
                for(int i=tail-1;i>=0;i--)
                {
                    tp=min(tp,edge[sta[i]].cap-edge[sta[i]].flow);
                }
                maxflow+=tp;
                for(int i=tail-1;i>=0;i--)
                {
                    edge[sta[i]].flow+=tp;
                    edge[sta[i]^1].flow-=tp;
                    if(edge[sta[i]].cap-edge[sta[i]].flow==0) tail=i;
                }
                u=edge[sta[tail]^1].to;
            }
            else if(cur[u]!=-1&&edge[cur[u]].cap>edge[cur[u]].flow&&dep[u]+1==dep[edge[cur[u]].to])
            {
                sta[tail++]=cur[u];
                u=edge[cur[u]].to;
            }
            else{
                while(u!=s&&cur[u]==-1) u=edge[sta[--tail]^1].to;
                cur[u]=edge[cur[u]].nxt;
            }
        }
    }
    return maxflow;
}
int main()
{
    ios::sync_with_stdio(false);
    int n,m,k;
    init();
    cin>>n>>m>>k;
    add(1,2,INF),add(1,3,k);
    for(int i=1;i<=n;++i) add(2,i+3,1),add(3,i+3,1);
    for(int i=1;i<=n;++i)
    {
        int x,y;
        cin>>x;
        for(int j=1;j<=x;++j)
        {
            cin>>y;
            add(i+3,y+n+3,1);
        }
    }
    for(int i=n+4;i<=n+m+4;++i) add(i,n+m+5,1);
    cout<<dinic(1,n+m+5,n+m+5)<<endl;
}

猜你喜欢

转载自www.cnblogs.com/isakovsky/p/11710822.html