poj 3281 拆点最大流

来源:互联网 发布:天猫魔盒必装软件 编辑:程序博客网 时间:2024/05/29 20:00

题意:一头牛需要一个食物跟一个饮料,每头牛只能选择特定的食物跟饮料,现有一定数量的食物饮料,问最多能满足几头牛


Input
Line 1: Three space-separated integers: N, F, and D
Lines 2.. N+1: Each line i starts with a two integers Fi and Di, the number of dishes that cow i likes and the number of drinks that cow i likes. The next Fi integers denote the dishes that cow i will eat, and the Di integers following that denote the drinks that cow i will drink.

Output

Line 1: A single integer that is the maximum number of cows that can be fed both food and drink that conform to their wishes



Sample Input
4 3 3
2 2 1 2 3 1
2 2 2 3 1 2
2 2 1 3 1 2
2 1 1 3 3


Sample Output
3


思路: 最大流,一头牛要满足两个条件(食物跟饮料),可以把牛放在中间来建边,将每头牛的点拆点保证只满足一次

用邻接矩阵存边,想快点的话可以改成邻接表。下标表示为 : s:0   t:401    食物:1-100   牛1:101-200  牛2:201-300  饮料:301-400;


  

#include <iostream>using namespace std;#include <string.h>#include <vector>#include <queue>int c[405][405];  // s:0 t:401int dep[405];int s=0,t=401;int const inf = 0x3f3f3f;  int min(int a,int b){return a>b?b:a;}int n,f,d;    int bfs(){      queue<int> q;      while(!q.empty())          q.pop();      memset(dep, -1, sizeof(dep));      dep[s] = 0;      q.push(s);      while(!q.empty()){          int u = q.front();  //cout<<u<<"  !!"<<endl;q.pop();  int v;//= u==0?1:u/100*100+101,ed=v+100;        for( v =0; v<=401 ; v++){              if(c[u][v] > 0 && dep[v] == -1){                  dep[v] = dep[u] + 1;                  q.push(v);              }          }      }      return dep[t] != -1;  }    int dfs(int u, int mi, int t){      if(u == t)          return mi;      int tmp;  int v;//= u==0?1:u/100*100+101,ed=v+100;    for( v=0 ; v<=401 ; v++){          if(c[u][v] > 0 && dep[v] == dep[u] + 1  && (tmp = dfs(v, min(mi, c[u][v]), t))){              c[u][v] -= tmp;              c[v][u] += tmp;              return tmp;          }      }      return 0;  }    int dinic()  {      int ans = 0, tmp;      while(bfs()){          while(1){              tmp = dfs(s, inf , t);  //cout<<tmp<<endl;            if(tmp == 0)                  break;              ans += tmp;          }      }      return ans;  }  int main()  {      while(~scanf("%d %d %d", &n, &f,&d)){          memset(c, 0, sizeof(c));          int u , i , j , k;for(i=1;i<=f;i++)c[s][i]=1;for(i=1;i<=d;i++)c[i+300][t]=1;        for(k=1;k<=n;k++){  c[k+100][k+200]=1;cin>>i>>j;while(i--){scanf("%d", &u);c[u][k+100]=1;}while(j--){scanf("%d", &u);c[k+200][u+300]=1;}        }          printf("%d\n", dinic());      }      return 0;  }