[USACO07OPEN]吃饭Dining

嘟嘟嘟

 

这应该是网络流入门题之一了,跟教辅的组成这道题很像。

把每一只牛看成书,然后对牛拆点,因为每一只牛只要一份,食物和饮料分别看成练习册和答案。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(' ')
 14 #define Mem(a, x) memset(a, x, sizeof(a))
 15 #define rg register
 16 typedef long long ll;
 17 typedef double db;
 18 const int INF = 0x3f3f3f3f;
 19 const db eps = 1e-8;
 20 const int maxn = 4e3 + 5;
 21 inline ll read()
 22 {
 23     ll ans = 0;
 24     char ch = getchar(), last = ' ';
 25     while(!isdigit(ch)) {last = ch; ch = getchar();}
 26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
 27     if(last == '-') ans = -ans;
 28     return ans;
 29 }
 30 inline void write(ll x)
 31 {
 32     if(x < 0) x = -x, putchar('-');
 33     if(x >= 10) write(x / 10);
 34     putchar(x % 10 + '0');
 35 }
 36 
 37 int n, f, d, t;
 38 
 39 struct Edge
 40 {
 41     int from, to, cap, flow;
 42 };
 43 vector<Edge> edges;
 44 vector<int> G[maxn];
 45 void addEdge(int from, int to)
 46 {
 47     edges.push_back((Edge){from, to, 1, 0});
 48     edges.push_back((Edge){to, from, 0, 0});
 49     int sz = edges.size(); 
 50     G[from].push_back(sz - 2);
 51     G[to].push_back(sz - 1);
 52 }
 53 
 54 int dis[maxn];
 55 bool bfs()
 56 {
 57     Mem(dis, 0); dis[0] = 1;
 58     queue<int> q; q.push(0);
 59     while(!q.empty())
 60     {
 61         int now = q.front(); q.pop();
 62         for(int i = 0; i < (int)G[now].size(); ++i)
 63         {
 64             Edge& e = edges[G[now][i]];
 65             if(!dis[e.to] && e.cap > e.flow)
 66             {
 67                 dis[e.to] = dis[now] + 1;
 68                 q.push(e.to);
 69             }
 70         }
 71     }
 72     return dis[t];
 73 }
 74 int cur[maxn];
 75 int dfs(int now, int res)
 76 {
 77     if(now == t || res == 0) return res;
 78     int flow = 0, f;
 79     for(int& i = cur[now]; i < (int)G[now].size(); ++i)
 80     {
 81         Edge& e = edges[G[now][i]];
 82         if(dis[e.to] == dis[now] + 1 && (f = dfs(e.to, min(res, e.cap - e.flow))) > 0)
 83         {
 84             e.flow += f;
 85             edges[G[now][i] ^ 1].flow -= f;
 86             flow += f;
 87             res -= f;
 88             if(res == 0) break;
 89         }
 90     }
 91     return flow;
 92 }
 93 
 94 int maxflow()
 95 {
 96     int flow = 0;
 97     while(bfs())
 98     {
 99         Mem(cur, 0);
100         flow += dfs(0, INF);
101     }
102     return flow;
103 }
104 
105 int main()
106 {
107     n = read(); f = read(); d = read(); 
108     t = (n << 1) + f + d + 1;
109     for(int i = 1; i <= f; ++i) addEdge(0, i);
110     for(int i = 1; i <= d; ++i) addEdge((n << 1) + f + i, t);
111     for(int i = 1; i <= n; ++i)
112     {
113         addEdge(f + i, f + n + i);
114         int f1 = read(), d1 = read();
115         for(int j = 1; j <= f1; ++j) 
116         {
117             int x = read();
118             addEdge(x, f + i);
119         }
120         for(int j = 1; j <= d1; ++j)
121         {
122             int x = read();
123             addEdge(f + n + i, (n << 1) + f + x);
124         }
125     }
126     write(maxflow()); enter;
127     return 0;
128 }
View Code

 

posted @ 2018-09-27 15:41  mrclr  阅读(206)  评论(0编辑  收藏  举报