最大流(周末训练赛)

题目链接:https://cn.vjudge.net/contest/155833#overview I题。

最大流(周末训练赛)_第1张图片

模板的话学长的模板很好用,建图就如上所示,代码如下。

代码:

#include
#include
#include
using namespace std;

const int oo=1e9;
const int mm=2e5+5;
const int mn=1e5+5;

int node,src,dest,edge;
int ver[mm],flow[mm],Next[mm];
int head[mn],work[mn],dis[mn],q[mn];

int Min(int a,int b)
{
    return aa:b;
}

void prepare(int _node,int _src,int _dest)
{
    node=_node,src=_src,dest=_dest;
    for(int i=0; i1;
    edge=0;
}


void Addedge(int u,int v,int c)
{
    ver[edge]=v,flow[edge]=c,Next[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,Next[edge]=head[v],head[v]=edge++;
}

bool Dinic_bfs()
{
    int i,u,v,l,r=0;
    for(i=0; i1;
    dis[q[r++]=src]=0;
    for(l=0; ll)
        for(i=head[u=q[l]]; i>=0; i=Next[i])
            if(flow[i]&&dis[v=ver[i]]<0)
            {
                dis[q[r++]=v]=dis[u]+1;
                if(v==dest)return 1;
            }
    return 0;
}

int Dinic_dfs(int u,int exp)
{
    if(u==dest)return exp;
    for(int &i=work[u],v,tmp; i>=0; i=Next[i])
        if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,Min(exp,flow[i])))>0)
        {
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            return tmp;
        }
    return 0;
}

int Dinic_flow()
{
    int i,ret=0,delta;
    while(Dinic_bfs())
    {
        for(i=0; ihead[i];
        while(delta=Dinic_dfs(src,oo)) ret+=delta;

    }
    return ret;
}

int main()
{
    int n,m,p;
    while(scanf("%d%d%d",&n,&m,&p)==3)
    {
        prepare(m+n+p+2,0,n+m+p+1);
        int mark[105];
        memset(mark,0,sizeof(mark));
        for(int i=1; i<=n; i++)
            Addedge(0,i,1);
        for(int i=1; i<=n; i++)
        {
            int k;
            scanf("%d",&k);
            for(int j=1; j<=k; j++)
            {
                int x;
                scanf("%d",&x);
                Addedge(i,x+n,1);
            }
        }

        for(int i=1; i<=p; i++)
        {
            int l,r,t,x;
            scanf("%d",&l);
            for(int j=1; j<=l; j++)
            {
                scanf("%d",&x);
                Addedge(n+x,n+m+i,1);
                mark[x]=1;
            }
            scanf("%d",&r);
            Addedge(n+m+i,n+m+p+1,r);
        }

        for(int i=1; i<=m; i++)
        {
            if(mark[i]==0)
                Addedge(n+i,n+m+p+1,1);
        }

        printf("%d\n",Dinic_flow());
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/a-clown/p/6623758.html

你可能感兴趣的:(最大流(周末训练赛))