zoukankan      html  css  js  c++  java
  • poj2289二分图多重匹配

    题意:给你一张二分图,求右边点到汇点的最小容量(保证流量为n)是多少

    题解:二分答案,每次重新建边跑最大流,看是不是为n就好了

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=2000+10,maxn=500000+10,inf=0x3f3f3f3f;
    
    struct edge{
        int to,Next,c;
    }e[maxn<<2];
    int cnt,head[N];
    int dis[N],num;
    pii pa[maxn<<1];
    void add(int u,int v,int c)
    {
      //  cout<<u<<" "<<v<<" "<<c<<endl;
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].Next=head[u];
        head[u]=cnt++;
        e[cnt].to=u;
        e[cnt].c=0;
        e[cnt].Next=head[v];
        head[v]=cnt++;
    }
    bool bfs(int s,int t)
    {
        memset(dis,-1,sizeof dis);
        dis[s]=0;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            if(x==t)return 1;
            for(int i=head[x];~i;i=e[i].Next)
            {
                int te=e[i].to;
                if(dis[te]==-1&&e[i].c>0)
                {
                    dis[te]=dis[x]+1;
                    q.push(te);
                }
            }
        }
        return 0;
    }
    int dfs(int x,int mx,int t)
    {
        if(x==t)return mx;
        int flow=0;
        for(int i=head[x];~i;i=e[i].Next)
        {
            int te=e[i].to,f;
            if(dis[te]==dis[x]+1&&e[i].c>0&&(f=dfs(te,min(mx-flow,e[i].c),t)))
            {
                e[i].c-=f;
                e[i^1].c+=f;
                flow+=f;
            }
        }
        if(!flow)dis[x]=-2;
        return flow;
    }
    int maxflow(int s,int t)
    {
        int ans=0,f;
        while(bfs(s,t))
        {
            while((f=dfs(s,inf,t)))ans+=f;
        }
        return ans;
    }
    void init()
    {
        cnt=0;
        memset(head,-1,sizeof head);
    }
    char p[N];
    int n,m;
    int getnum(int l,int r)
    {
        int ans=0;
        for(int i=l;i<=r;i++)
            ans=ans*10+p[i]-'0';
        return ans;
    }
    bool ok(int x,int s,int t)
    {
        init();
        for(int i=0;i<num;i++)add(pa[i].fi,pa[i].se,1);
        for(int i=1;i<=m;i++)add(i+n,t,x);
        return maxflow(s,t)>=n;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            if(!n&&!m)break;
            int s=n+m+1,t=n+m+2;
            num=0;
            for(int i=1;i<=n;i++)pa[num++]=mp(s,i);
            getchar();
            for(int i=1;i<=n;i++)
            {
                gets(p);
                int len=strlen(p),j=0;
                while(j<len&&p[j]!=' ')j++;
                j++;
                for(;j<len;j++)
                {
                    int k=j;
                    while(k+1<len&&p[k+1]!=' ')k++;
                    int res=getnum(j,k)+1;
                    pa[num++]=mp(i,res+n);
                    j=k+1;
                }
            }
            int l=0,r=n+1;
            while(r-l>1)
            {
                int m=(l+r)/2;
                if(ok(m,s,t))r=m;
                else l=m;
            }
            printf("%d
    ",r);
    
        }
        return 0;
    }
    /********************
    
    ********************/
    View Code
  • 相关阅读:
    现代操作系统读书笔记 2
    java8 中 ImageIO 读取 tiff 格式的图片失败
    word 转 pdf,c#代码
    spring 技术内幕读书笔记1
    操作系统精髓与设计读书笔记1
    手把手教你WEB套打程序开发
    WEB打印控件Lodop使用体会
    listview下拉刷新 上拉(滑动分页)加载更多
    如何解析android访问webservice返回的SoapObject数据(可用)
    统计子串在另一个字符中出现的次数
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7826626.html
Copyright © 2011-2022 走看看