POJ 3281 -- Dining

来源:互联网 发布:淘宝怎么加陌生人好友 编辑:程序博客网 时间:2024/05/24 07:43

代码实现:

#include<cstdio>#include<cstring>#include<queue>#include<iostream>#include<vector>#define Min(a,b) ((a)<(b)?(a):(b))#define Max(a,b) ((a)>(b)?(a):(b))#define INF 0x3f3f3f3f#define IN64 0x3f3f3f3f3f3f3f3fllusing namespace std;const int N=410, M=40610;int n, f, d, s, t, top;int head[N], gap[N], cur[N], dis[N], vis[N], pre[N], num1[210], num2[210];struct Edge{    int to, next, flow;    Edge(int _to = 0, int _next = 0, int _flow = 0):to(_to), next(_next), flow(_flow){}}edge[M];void Addedge(int from, int to, int flow){    edge[top] = Edge(to, head[from], flow);    head[from] = top++;    edge[top] = Edge(from, head[to], 0);    head[to] = top++;}void Bfs(){    queue<int> q;    memset(gap, 0, sizeof(gap));    memset(dis, -1, sizeof(dis));    gap[0] = 1; dis[t] = 0; q.push(t);    while(!q.empty()){        int u = q.front(); q.pop();        for(int i = head[u]; i+1; i = edge[i].next){            if(dis[edge[i].to] == -1){                dis[edge[i].to] = dis[u] + 1;                gap[dis[edge[i].to]] ++;                q.push(edge[i].to);            }        }    }}int Sap(){    Bfs();    memset(pre, -1, sizeof(pre));    for(int i = s; i <= t; ++i) cur[i] = head[i];    int u = s, cur_flow, max_flow = 0, neck, tmp;    while(dis[s] <= t){        if(u == t){            cur_flow = INF;            for(int i = s; i != t; i = edge[cur[i]].to){                if(cur_flow > edge[cur[i]].flow){                    cur_flow = edge[cur[i]].flow;                    neck = i;                }            }            for(int i = s; i != t; i = edge[cur[i]].to){                tmp = cur[i];                edge[tmp].flow -= cur_flow;                edge[tmp^1].flow += cur_flow;            }            max_flow += cur_flow;            u = neck;        }        int i;        for(i = cur[u]; i + 1; i = edge[i].next){            if(edge[i].flow && dis[u] == dis[edge[i].to] + 1) break;        }        if(i != -1){            cur[u] = i;            pre[edge[i].to] = u;            u = edge[i].to;        }else{            if(--gap[dis[u]] == 0) break;            cur[u] = head[u];            int mindis = t;            for(i = head[u]; i + 1; i = edge[i].next)                if(edge[i].flow && mindis > dis[edge[i].to]) mindis = dis[edge[i].to];            dis[u] = mindis + 1;            gap[dis[u]] ++;            if(u != s) u = pre[u];        }    }    return max_flow;}int main(){    while(~scanf("%d%d%d", &n, &f, &d)){        memset(head, -1, sizeof(head));        top = s = 0;        t = n*2 + f + d + 1;        int tmp = f + d, fi, di, num;        for(int i = 1; i <= f; ++i) Addedge(s, i, 1);        for(int i = 1; i <= d; ++i) Addedge(i+f, t, 1);        for(int i = 1; i <= n; ++i){            scanf("%d%d", &fi, &di);            Addedge(i+tmp, i+tmp+n, 1);            for(int j = 1; j <= fi; ++j){                scanf("%d", &num);                Addedge(num, i+tmp, 1);            }            for(int j = 1; j <= di; ++j){                scanf("%d", &num);                Addedge(i+tmp+n, num+f, 1);            }        }        int res = Sap();        printf("%d\n", res);    }}


0 0