POJ

来源:互联网 发布:网络游戏发展史 知乎 编辑:程序博客网 时间:2024/06/16 07:44

题目大意:

大概就是给你n头牛和m个位置,然后告诉你每个牛喜欢在哪些摊位上面产奶,问你如何分配这些牛才能得到最多的产奶量。

网络流建图:

超级源点连到每头牛上,容量为1,每头牛连到其能产奶的摊位上,容量为1,每个摊位连到超级汇点,容量为1。

代码

#include<iostream>#include<stdio.h>#include<math.h>#include<string.h>#include<queue>#include<map>#define inf 0x3f3f3f3f#define maxn 1500using namespace std;struct Edge{    int from,to,cap,flow;    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}};int n;int m;vector<Edge>edge;vector<int>G[maxn];int a[maxn];int p[maxn];void init(int x){    for(int i=0;i<x;i++)G[i].clear();    edge.clear();}void add_edge(int from,int to,int cap){    edge.push_back(Edge(from,to,cap,0));    edge.push_back(Edge(to,from,0,0));    int lm=edge.size();    G[from].push_back(lm-2);    G[to].push_back(lm-1);}int maxflow(int s,int t){    int flow=0;    while(1)    {        memset(a,0,sizeof(a));        queue<int>Q;        Q.push(s);        a[s]=inf;        while(!Q.empty())        {            int x=Q.front();Q.pop();            for(int i=0;i<G[x].size();i++)            {                Edge& e=edge[G[x][i]];                if(!a[e.to]&&e.cap>e.flow)                {                    p[e.to]=G[x][i];                    a[e.to]=min(a[x],e.cap-e.flow);                    Q.push(e.to);                }            }            if(a[t])break;        }        if(!a[t])break;        for(int u=t;u!=s;u=edge[p[u]].from)        {            edge[p[u]].flow+=a[t];            edge[p[u]^1].flow-=a[t];        }        flow+=a[t];    }    return flow;}int main(){    while(cin>>n>>m)    {        init(maxn);        memset(p,0,sizeof(p));        for(int i=1;i<=n;i++)        {            add_edge(0,i,1);            int num;            int x;            scanf("%d",&num);            for(int j=0;j<num;j++)            {                scanf("%d",&x);                add_edge(i,x+n,1);            }        }        for(int i=1;i<=m;i++)        {            add_edge(i+n,m+n+1,1);        }        printf("%d\n",maxflow(0,m+n+1));    }}
0 0
原创粉丝点击