poj 3281 Dinicing

    简单建图,source->food->cow1->cow2->drink->collection

    一开始数组开小了一直TLE,居然不是RE……

/*
author:jxy
lang:C/C++
university:China,Xidian University
**If you need to reprint,please indicate the source**
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#define INF 1E9
using namespace std;
#define maxn 405
#define maxm 160005
int d[maxn],first[maxn],cur[maxn],cnt;
struct edge
{
    int v,c,f,next;
    edge(int &a,int &b,int cc):v(b),c(cc),f(0)
    {
        next=first[a];
        first[a]=cnt++;
    }
    edge(){};
}e[maxm];
inline void addedge(int v,int u,int c)
{
    e[cnt]=edge(v,u,c);
    e[cnt]=edge(u,v,0);
}
queue<int> q;
int vis[maxn];
int S,E;

int bfs()
{
    int v,u;
    memset(vis,0,sizeof(vis));
    while(!q.empty())q.pop();
    q.push(S);
    d[S]=0;vis[S]=1;
    while(!q.empty())
    {
        v=q.front();q.pop();
        for(int i=first[v];~i;i=e[i].next)
        {
            u=e[i].v;
            if(!vis[u]&&e[i].c>e[i].f)
            {
                vis[u]=1;
                q.push(u);
                d[u]=d[v]+1;
            }
        }
    }
    return vis[E];
}
int dfs(int v,int re)
{
    if(v==E||re==0)return re;
    int f=0,u,t;
    for(int &i=cur[v];~i;i=e[i].next)
    {
        u=e[i].v;
        if(d[v]+1==d[u]&&(t=dfs(u,min(re,e[i].c-e[i].f)))>0)
        {
            e[i].f+=t;e[i^1].f-=t;
            f+=t;re-=t;
            if(!re)break;
        }
    }
    return f;
}
int main()
{
    int n,F,D;
    while(~scanf("%d%d%d",&n,&F,&D))
    {
        memset(first,-1,sizeof(first));
        cnt=0;
        int i,j,a,b,t=F+D;
        S=0,E=2*n+F+D+1;
        for(i=1;i<=F;i++)
            addedge(0,i,1);
        for(i=F+1;i<=t;i++)
            addedge(i,E,1);
        for(i=t+n+1;i<E;i++)
            addedge(i-n,i,1);
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);
            while(a--)
            {
                scanf("%d",&j);
                addedge(j,i+t,1);
            }
            while(b--)
            {
                scanf("%d",&j);
                addedge(i+t+n,F+j,1);
            }
        }
        int ans=0;
        while(bfs())
        {
            for(int i=0;i<=E;i++)
               cur[i]=first[i];
            ans+=dfs(S,INF);
        }
        printf("%d\n",ans);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值