• poj3281 Dining


    传送门

    给定n头牛 a种食物 b种饮料

    每种食物/饮料只能用一次

    一头牛有限定的食物/饮料选择集合

    食物饮料均满足则统计个数++ 求最大个数

    Solution:

    每个牛只配一次 所以拆点

    然后就食物连源点 饮料连汇点

    牛左右部连边

    每个牛左边连食物右边连饮料

    上述所有边权均为1

    直接最大流完事

    (发blog的顺序好像和做的顺序不大一样)

    (感觉main压成一行好爽)

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<iostream>
     5 #include<algorithm>
     6 #define ms(a,b) memset(a,b,sizeof a)
     7 #define rep(i,a,n) for(int i = a;i <= n;i++)
     8 #define per(i,n,a) for(int i = n;i >= a;i--)
     9 #define inf 2147483647
    10 using namespace std;
    11 typedef long long ll;
    12 typedef double D;
    13 #define eps 1e-8
    14 ll read() {
    15     ll as = 0,fu = 1;
    16     char c = getchar();
    17     while(c < '0' || c > '9') {
    18         if(c == '-') fu = -1;
    19         c = getchar();
    20     }
    21     while(c >= '0' && c <= '9') {
    22         as = as * 10 + c - '0';
    23         c = getchar();
    24     }
    25     return as * fu;
    26 }
    27 const int N = 10005;
    28 //head
    29 int n,A,B;
    30 int s = N-1,t = N-2;
    31 int head[N],nxt[N<<1],mo[N<<1],cst[N<<1],cnt = 1;
    32 void _add(int x,int y,int w) {
    33     mo[++cnt] = y;
    34     cst[cnt] = w;
    35     nxt[cnt] = head[x];
    36     head[x] = cnt;
    37 }
    38 void add(int x,int y) {if(x^y) _add(x,y,1),_add(y,x,0);}
    39 
    40 int dep[N],cur[N];
    41 bool bfs() {
    42     queue<int> q;
    43     memcpy(cur,head,sizeof cur);
    44     ms(dep,0),q.push(s),dep[s] = 1;
    45     while(!q.empty()) {
    46         int x = q.front();
    47         q.pop();
    48         for(int i = head[x];i;i = nxt[i]) {
    49             int sn = mo[i];
    50             if(!dep[sn] && cst[i]) {
    51                 dep[sn] = dep[x] + 1;
    52                 q.push(sn);
    53             }
    54         }
    55     }
    56     return dep[t];
    57 }
    58 
    59 int dfs(int x,int flow) {
    60     if(x == t || flow == 0) return flow;
    61     int res = 0;
    62     for(int &i = cur[x];i;i = nxt[i]) {
    63         int sn = mo[i];
    64         if(dep[sn] == dep[x] + 1 && cst[i]) {
    65             int d = dfs(sn,min(cst[i],flow - res));
    66             if(d) {
    67                 cst[i] -= d,cst[i^1] += d;
    68                 res += d;
    69                 if(res == flow) break;
    70             }
    71         }
    72     }
    73     if(res ^ flow) dep[x] = 0;
    74     return res;
    75 }
    76 
    77 int DINIC() {
    78     int ans = 0;
    79     while(bfs()) ans += dfs(s,inf);
    80     return ans;
    81 }
    82 
    83 int idx(int x,int f) {return x + f * 1005;}
    84 
    85 void init() {
    86     n = read(),A = read(),B = read();
    87     rep(i,1,n) {
    88         int X = read(),Y = read();
    89         rep(j,1,X) add(idx(read(),0),idx(i,1));
    90         rep(j,1,Y) add(idx(i,2),idx(read(),3));
    91         add(idx(i,1),idx(i,2));
    92     }
    93     rep(i,1,A) add(s,idx(i,0));
    94     rep(i,1,B) add(idx(i,3),t);
    95 }
    96 
    97 int main() {init(),printf("%d
    ",DINIC());}
  • 相关阅读:
    .NET使用ICSharpCode.SharpZipLib压缩/解压文件
    在vs2005中使用AnkhSvn服务端IP改变无法连接
    repeater标签双重循环的使用
    在vs2005中使用SVN进行版本管理
    jmeter--响应断言
    jmeter--十三种断言方式介绍
    jmeter--参数化的四种方法
    jmeter--元件的作用域与执行顺序
    jmeter--使用badboy录制脚本
    jmeter--基本组件介绍
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/10011966.html
Copyright © 2020-2023  润新知