2016-2017 ACM-ICPC East Central North America Regional Contest (ECNA 2016) I 匹配,最大流
2016-2017 ACM-ICPC East Central North America Regional Contest (ECNA 2016)
I 题意:n个孩子,m个玩具,玩具有p个种类。每个孩子有喜欢的玩具,每个玩具有可能属于一个种类。问最多多少个孩子可以分配到一个他喜欢的玩具。
tags:SB匹配,建好图跑个最大流就好。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a;i<=b;i++) #define per(i,b,a) for (int i=b;i>=a;i--) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 1005; int n, m, p, k, l, r, st, ed, ai; int head[N], dis[N], tot, cur[N], remain[N<<1]; struct Edge{int to, next; } e[N<<1]; bool vis[N]; void Addedge(int u, int v, int w) { e[tot]=(Edge){v, head[u] }; remain[tot]=w; head[u]=tot++; e[tot]=(Edge){u, head[v] }; remain[tot]=0; head[v]=tot++; } void Init() { tot=0, st=0, ed=n+m+p+5; mes(head, -1); } bool bfs(int st, int ed) { rep(i,st,ed) cur[i]=head[i]; mes(dis, -1); queue<int >q; q.push(st); dis[st]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u]; i!=-1; i=e[i].next) { int to=e[i].to; if(dis[to]==-1 && remain[i]) { q.push(to); dis[to]=dis[u]+1; if(to==ed) return true; } } } return false; } int dfs(int now, int ed, int flow) { if(now==ed || flow==0) return flow; int s, ans=0; for(int &i=cur[now]; i!=-1; i=e[i].next) { int to=e[i].to; if(dis[to]==dis[now]+1 && (s=dfs(to,ed,min(flow, remain[i])))) { ans+=s, flow-=s; remain[i]-=s, remain[i^1]+=s; if(flow==0) break; } } return ans; } int dinic(int st, int ed) { int s, ans=0; while(bfs(st,ed)) while(s=dfs(st,ed,INF)) ans+=s; return ans; } int main() { scanf("%d %d %d", &n, &m, &p); Init(); rep(i,1,n) { scanf("%d", &k); rep(j,1,k) scanf("%d", &ai), Addedge(i, ai+n, 1); Addedge(st, i, 1); } mes(vis,0); rep(i,1,p) { scanf("%d", &l); rep(j,1,l) scanf("%d", &ai), Addedge(ai+n, i+n+m, 1), vis[ai]=1; scanf("%d", &r); Addedge(i+n+m, ed, r); } rep(i,1,m) if(vis[i]==0) Addedge(i+n, ed, 1); printf("%d\n", dinic(st, ed)); return 0; }