题意:
若干个勇士,每个勇士只能杀特定的怪物。每个勇士只能杀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; }