poj 2112 Optimal Milking 二分图多重匹配

来源:互联网 发布:编程基本算法 编辑:程序博客网 时间:2024/04/30 20:19
#include<stdio.h>#include<string.h>#include<queue>#include<vector>#include<map>#include<iostream>using namespace std;const int N=1024*10;const int inf=10000000;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];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 flow=0;    while(BFS())    {        memset(cur,0,sizeof(cur));        flow+=DFS(s,inf);    }    return flow;}int gt[500][500];int main(){    int l,r,mid,n,m,u,v,c,i,j,k,pt;    int K,C,M;    while(scanf("%d%d%d",&K,&C,&M)!=EOF)    {        s=0;        n=K+C;        t=n+1;        memset(gt,0,sizeof(gt));        for(i=1; i<=n; i++)        {            for(j=1; j<=n; j++)            {                scanf("%d",&gt[i][j]);                if(gt[i][j]==0&&i!=j)                    gt[i][j]=inf;            }        }        for(k=1; k<=n; k++)        for(i=1; i<=n; i++)                for(j=1; j<=n; j++)                    gt[i][j]=min(gt[i][j],gt[i][k]+gt[k][j]);        l=0;        r=10000;        while(l<r)        {            mid=(l+r)/2;            for(i=0; i<=t; i++) G[i].clear();            edges.clear();            for(i=K+1;i<=n;i++)                addedge(s,i,1);            for(i=1;i<=K;i++)                addedge(i,t,M);            for(i=K+1;i<=n;i++)                for(j=1;j<=K;j++)                    if(gt[i][j]<=mid&&gt[i][j]!=0)                        addedge(i,j,1);            int ans=Maxflow();            if(ans>=C)            {                r=mid;                pt=r;            }            else                l=mid+1;        }        printf("%d\n",pt);    }    return 0;}
0 0
原创粉丝点击