POJ 3281 最大流+建图

来源:互联网 发布:知错改错不认错的说说 编辑:程序博客网 时间:2024/06/08 20:16

题目大意:有n头牛,f种草料,d种水,每种草料和每种水仅有一个单位,每头牛要吃一个单位草料和喝一个单位水。每头牛只对一部分草料和一部分水感兴趣。问你最多能完全满足多少头牛(草料和水均满意)?


分析:经典构图题:用拆点来限制流量,超级源点与每种食物相连,负载为1。每头牛拆点,负载为1(此处限制流量,一头牛只能转移一的流量)。每头牛拆点的出点与所有满意的食物相连,负载为1;每头牛拆点的入点再与所有满意的水相连,负载为1,每种水再与超级汇点相连,负载为1。最终看最大流跑出多少就是最大的,能够双双满足的牛的数量。


图解:




(另外有一种变体是食物和饮料数量不是1,则相应改变超级源点和超级汇点连接的边为对应数量即可。)


上代码:

[cpp] view plain copy
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<algorithm>  
  4. #include<queue>  
  5. #include<cstring>  
  6. using namespace std;  
  7.   
  8. const int MAXM = 251000;  
  9. const int MAXN = 510;  
  10. const int INF = 0x3f3f3f3f;  
  11.   
  12. struct Edge  
  13. {  
  14.     int to, cap, next;  
  15. };  
  16.   
  17. Edge edge[MAXM];  
  18. int level[MAXN];  
  19. int head[MAXN];  
  20. int src, des, cnt;  
  21.   
  22. void addedge( int from, int to, int cap )  
  23. {  
  24.     edge[cnt].to = to;  
  25.     edge[cnt].cap = cap;  
  26.     edge[cnt].next = head[from];  
  27.     head[from] = cnt++;  
  28.   
  29.     swap( from, to );  
  30.   
  31.     edge[cnt].to = to;  
  32.     edge[cnt].cap = 0;  
  33.     edge[cnt].next = head[from];  
  34.     head[from] = cnt++;  
  35. }  
  36.   
  37. int bfs()  
  38. {  
  39.     memset( level, -1, sizeof level );  
  40.     queue<int>q;  
  41.     while (!q.empty())  
  42.         q.pop();  
  43.   
  44.     level[src] = 0;  
  45.     q.push( src );  
  46.   
  47.     while (!q.empty())  
  48.     {  
  49.         int u = q.front();  
  50.         q.pop();  
  51.   
  52.         for (int i = head[u]; i != -1; i = edge[i].next)  
  53.         {  
  54.             int v = edge[i].to;  
  55.             if (edge[i].cap > 0 && level[v] == -1)  
  56.             {  
  57.                 level[v] = level[u] + 1;  
  58.                 q.push( v );  
  59.             }  
  60.         }  
  61.     }  
  62.     return level[des] != -1;  
  63. }  
  64.   
  65. int dfs( int u, int f )  
  66. {  
  67.     if (u == des) return f;  
  68.     int tem;  
  69.     for (int i = head[u]; i != -1; i = edge[i].next)  
  70.     {  
  71.         int v = edge[i].to;  
  72.         if (edge[i].cap>0&&level[v] == level[u] + 1)  
  73.         {  
  74.             tem = dfs( v, min( f, edge[i].cap ) );  
  75.             if (tem > 0)  
  76.             {  
  77.                 edge[i].cap -= tem;  
  78.                 edge[i^1].cap += tem;  
  79.                 return tem;  
  80.             }  
  81.         }  
  82.     }  
  83.     level[u] = -1;  
  84.     return 0;  
  85. }  
  86.   
  87.   
  88. int Dinic()  
  89. {  
  90.     int ans = 0, tem;  
  91.   
  92.     while (bfs())  
  93.     {  
  94.         while ((tem = dfs( src, INF )) > 0)  
  95.         {  
  96.             ans += tem;  
  97.         }  
  98.     }  
  99.     return ans;  
  100. }  
  101.   
  102.   
  103.   
  104. int main()  
  105. {  
  106.     int n, f, d;  
  107.     src = 0;  
  108.     des = 505;  
  109.     while (cin >> n>>f>>d)  
  110.     {  
  111.         memset( head, -1, sizeof head );  
  112.         cnt = 0;  
  113.         for (int i = 1; i <= f; i++)  
  114.             addedge( src, i + 200, 1 );  
  115.         for (int i = 1; i <= d; i++)  
  116.             addedge( i + 300, des, 1 );  
  117.   
  118.         for (int i = 1; i <= n; i++)  
  119.         {  
  120.             addedge( i, i + 100, 1 );  
  121.             int F, D;  
  122.             cin >> F>>D;  
  123.             for (int j = 1; j <= F; j++)  
  124.             {  
  125.                 int tem;  
  126.                 cin >> tem;  
  127.                 addedge( tem + 200, i, 1 );  
  128.             }  
  129.             for (int j = 1; j <= D; j++)  
  130.             {  
  131.                 int tem;  
  132.                 cin >> tem;  
  133.                 addedge( i+100, tem + 300, 1 );  
  134.             }  
  135.         }  
  136.         cout << Dinic() << endl;  
  137.     }  
  138.     return 0;  
  139.   
  140. }  

0 0