poj 3189 Steady Cow Assignment 二分图多重匹配

来源:互联网 发布:linux查找软件命令 编辑:程序博客网 时间:2024/06/05 18:25
#include<stdio.h>#include<string.h>#include<queue>#include<vector>using namespace std;const int N=1200;const int inf=1<<24;struct Edge{    int from,to,cap,flow;};vector<Edge>edges;vector<int>G[N];int s,t;int vis[N];int d[N];int cur[N];int g[N][30];void AddEdge(int from,int to,int cap){    Edge tp;    tp.from=from,tp.to=to,tp.cap=cap,tp.flow=0;    edges.push_back(tp);    tp.from=to,tp.to=from,tp.cap=0,tp.flow=0;    edges.push_back(tp);    int g_size=edges.size();    G[from].push_back(g_size-2);    G[to].push_back(g_size-1);}bool BFS(){    memset(vis,0,sizeof(vis));    queue<int>Q;    Q.push(s);    d[s]=0;    vis[s]=1;    while(!Q.empty())    {        int x=Q.front();        Q.pop();        for(int i=0; i<G[x].size(); i++)        {            Edge &e=edges[G[x][i]];            if(!vis[e.to]&&e.cap>e.flow)            {                vis[e.to]=1;                d[e.to]=d[x]+1;                Q.push(e.to);            }        }    }    return vis[t];}int DFS(int x,int a){    if(x==t||a==0) return a;    int flow=0,f;    for(int &i=cur[x]; i<G[x].size(); i++)    {        Edge &e=edges[G[x][i]];        if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)        {            e.flow+=f;            edges[G[x][i]^1].flow-=f;            flow+=f;            a-=f;            if(a==0) break;        }    }    if(!flow) d[x] = -1;    return flow;}int Maxflow(int st,int ed){    int flow=0;    while(BFS())    {        memset(cur,0,sizeof(cur));        flow+=DFS(st,inf);    }    return flow;}int main(){    int i,j,k,n,m,u,v,c,mp[N],r,l,f;    while(~scanf("%d%d",&n,&m))    {        s=0;        t=n+m+1;        for(i=1; i<=n; i++)            for(j=1; j<=m; j++)                scanf("%d",&g[i][j]);        for(i=1; i<=m; i++)            scanf("%d",&mp[i]);        l=0,r=m;        while(l<r)        {            f=0;            k=(l+r)/2;            for(int x=1; x+k<=m; x++)            {                //k=(l+r)/2;                edges.clear();                for(i=0; i<N; i++) G[i].clear();                for(i=1; i<=n; i++)                    AddEdge(s,i,1);                for(i=n+1; i<=n+m; i++)                    AddEdge(i,t,mp[i-n]);                for(i=1; i<=n; i++)                    for(j=x; j<=x+k; j++)                        AddEdge(i,g[i][j]+n,1);                if(Maxflow(s,t)==n)                {                    f=1;                    break;                }            }            if(f==1) r=k;            else l=k+1;        }        printf("%d\n",r+1);    }    return 0;}
0 0
原创粉丝点击