分析:
求最大流
建图:
拆点 牛拆成左边与食物相连的左牛 和 右边与饮料相连的右牛
1、s->食物 连边
2、食物->左牛
3、左牛->右牛
4、右牛->饮料
5、饮料->t
边的方向为 s->食物->左牛->右牛->饮料->t
#include#include #include #include #include using namespace std;const int maxn = 500 + 5;const int INF = 100000000;struct Edge{ int from, to, cap, flow;};struct Dinic{ int n, m, s, t; vector edges; vector G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; void init(int n) { this->n = n; for(int i=0; i<=n; ++i) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap) { edges.push_back((Edge){from, to, cap, 0}); edges.push_back((Edge){to, from, 0, 0}); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { memset(vis, 0, sizeof vis ); queue Q; Q.push(s); vis[s] = 1; d[s] = 0; while(!Q.empty()) { int x = Q.front(); Q.pop(); for(int i=0; i e.flow) { vis[e.to] = 1; d[e.to] = d[x] + 1; Q.push(e.to); } } } return vis[t]; } int DFS(int x, int a) { if(x == t || a == 0) return a; int flow = 0, f; for(int& i = cur[x]; i 0) { e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a==0) break; } } return flow; } int Maxflow(int s, int t) { this->s = s; this->t =t; int flow = 0; while(BFS()){ memset(cur, 0, sizeof cur ); flow += DFS(s, INF); } return flow; }};Dinic solver;int main(){ int N, F, D; int i, j; scanf("%d%d%d", &N, &F, &D); int s = 0, t = 2*N + F + D; solver.init(t+1); for(i=1; i<=N; ++i) solver.AddEdge(i, N+i, 1); for(i=1; i<=N; ++i) { int f, d, x; scanf("%d%d", &f, &d); for(j=1; j<=f; ++j) { scanf("%d", &x); solver.AddEdge(2*N+x, i, 1); } for(j=1; j<=d; ++j) { scanf("%d", &x); solver.AddEdge(N+i, 2*N+F+x, 1); } } for(i=1; i<=F; ++i) solver.AddEdge(s, 2*N + i, 1); for(i=1; i<=D; ++i) solver.AddEdge(2*N + F + i, t, 1); int ans = solver.Maxflow(s, t); printf("%d\n", ans); return 0;}
版权声明:本文博主原创文章,博客,未经同意不得转载。