标签:
分析:
数学模型是三个集合A,B,C,(a,b,c)构成一个匹配。因为图一个点只能匹配一次,把a拆点a‘,a",
在可以匹配的点上连边,s - b - a‘ - a" - c - t,然后最大流就好了。
/********************************************************* * ------------------ * * author AbyssalFish * **********************************************************/ #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; const int maxv = 402, maxe = 40600+2; int hd[maxv],to[maxe],nx[maxe],ec, cap[maxe]; #define eachEage int i = hd[u]; i; i = nx[i] void add(int u,int v,int cp) { nx[++ec] = hd[u]; to[ec] = v; cap[ec] = cp; hd[u] = ec; } void Add(int u,int v,int cp = 1) { add(u,v,cp); add(v,u,0); } int S,T; int lv[maxv]; bool vis[maxv]; int que[maxv]; bool bfs() { memset(vis,0,sizeof(vis)); int *q = que, l = 0, r = 0; lv[q[r++] = S] = 0; vis[S] = true; while(l<r){ int u = q[l++]; for(eachEage){ int v = to[i]; if(!vis[v] && cap[i]){ lv[v] = lv[u] + 1; vis[v] = true; q[r++] = v; } } } return vis[T]; } int cur[maxv]; int aug(int u,int a) { if(u == T || !a) return a; int flow = 0,f; for(int &i = cur[u]; i; i = nx[i]){ int v = to[i]; if(lv[v] == lv[u]+1 && (f = aug(v,min(a,cap[i])))){ flow += f; a -= f; cap[i] -= f; cap[i^1] += f; if(!a) break; } } return flow; } int maxFlow() { int flow = 0; while(bfs()){ memcpy(cur,hd,sizeof(int)*(T+1)); flow += aug(S,1<<30); } return flow; } //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif ec = 1; int N, F, D; scanf("%d%d%d",&N,&F,&D); int N2 = N*2, N2F = N2+F; S = 0; T = N2F+D+1; for(int i = 1; i <= N; i++){ int Fi, Di, x; scanf("%d%d",&Fi,&Di); while(Fi--){ scanf("%d", &x); Add(N2+x,i); } Add(i,N+i); while(Di--){ scanf("%d", &x); Add(N+i,N2F+x); } } for(int i = 1; i <= F; i++) Add(S,N2+i); for(int i = 1; i <= D; i++) Add(N2F+i,T); printf("%d\n", maxFlow()); return 0; }
标签:
原文地址:http://www.cnblogs.com/jerryRey/p/4947539.html