• bzoj 1305: [CQOI2009]dance 二分+網絡流判定


    1305: [CQOI2009]dance跳舞

    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 1340  Solved: 581
    [Submit][Status]

    Description

    一次舞会有n个男孩和n个女孩。每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首(或更多)舞曲。有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”)。每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞。给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲?

    Input

    第一行包含两个整数n和k。以下n行每行包含n个字符,其中第i行第j个字符为'Y'当且仅当男孩i和女孩j相互喜欢。

    Output

    仅一个数,即舞曲数目的最大值。

    Sample Input

    3 0
    YYY
    YYY
    YYY

    Sample Output

    3

    HINT

    N<=50 K<=30

    Source

    加强数据By dwellings and liyizhen2

    這道題知道是二分+網絡流後,就是完完全全的水題了。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    #include<queue>
    using namespace std;
    #ifdef WIN32
    #define LL "%I64d"
    #else
    #define LL "%lld"
    #endif
    #define MAXN 55
    #define MAXV MAXN*MAXN*2
    #define MAXE MAXV*2
    #define INF 0x3f3f3f3f
    #define INFL 0x3f3f3f3f3f3f3f3fLL
    typedef long long qword;
    inline int nextInt()
    {
            char ch;
            int x=0;
            bool flag=false;
            do
                    ch=getchar(),flag=(ch=='-')?true:flag;
            while(ch<'0'||ch>'9');
            do x=x*10+ch-'0';
            while (ch=getchar(),ch<='9' && ch>='0');
            return x*(flag?-1:1);
    }
    
    int n,m;
    
    char mp[MAXN][MAXN];
    struct Edge
    {
            int val,np;
            Edge *next,*neg;
    }E[MAXE],*V[MAXV];
    int tope=1;
    int sour=0,sink=1;
    inline void addedge(int x,int y,int z)
    {
            //cout<<"Add edge:<"<<tope+1<<">"<<x<<" "<<y<<":"<<z<<endl;
            E[++tope].np=y;
            E[tope].val=z;
            E[tope].next=V[x];
            V[x]=&E[tope];
    
            E[++tope].np=x;
            E[tope].val=0;
            E[tope].next=V[y];
            V[y]=&E[tope];
    
            E[tope].neg=&E[tope-1];
            E[tope-1].neg=&E[tope];
    }
    int q[MAXV],lev[MAXV];
    int vis[MAXV],bfstime=0;
    bool bfs()
    {
            int i,j;
            int head=-1,tail=0;
            Edge *ne;
            lev[sour]=1;
            vis[sour]=++bfstime;
            q[0]=sour;
            while (head<tail)
            {
                    for (ne=V[q[++head]];ne;ne=ne->next)
                    {
                            if (!ne->val || vis[ne->np]==bfstime)continue;
                            q[++tail]=ne->np;
                            vis[ne->np]=bfstime;
                            lev[ne->np]=lev[q[head]]+1;
                    }
            }
            return vis[sink]==bfstime;
    }
    int dfs(int now,int maxf)
    {
            int ret=0,t;
            if (now==sink || !maxf)return maxf;
            Edge* ne;
            for (ne=V[now];ne;ne=ne->next)
            {
                    if (!ne->val || lev[ne->np]!=lev[now]+1)continue;
                    t=dfs(ne->np,min(maxf,ne->val));
                    ne->val-=t;
                    ne->neg->val+=t;
                    maxf-=t;
                    ret+=t;
                    //cout<<"Flow:"<<now<<"-"<<ne->np<<":"<<x<<"("<<ne->val<<")"<<endl;
            }
            if (!ret)lev[now]=-1;
            return ret;
    }
    int dinic()
    {
            int ret=0;
            while (bfs())
            {
                    ret+=dfs(sour,INF);
            }
            return ret;
    }
    
    int main()
    {
            freopen("input.txt","r",stdin);
            //freopen("output.txt","w",stdout);
            int i,j,k;
            int x,y,z;
            scanf("%d%d
    ",&n,&m);
            for (i=0;i<n;i++)
            {
                    fgets(mp[i],MAXN,stdin);
            }
            int ans=0;
            int l=0,r=n+1,mid;
            while (l+1<r)
            {
                    memset(V,0,sizeof(V));
                    tope=-1;
                    mid=(l+r)>>1;
                    for (i=0;i<n;i++)
                    {
                            addedge(sour,2+i,mid);
                            addedge(2+i,2+i+n*2,m);
                            addedge(2+i+n,sink,mid);
                            addedge(2+i+n+n*2,2+i+n,m);
                    }
                    for (i=0;i<n;i++)
                    {
                            for (j=0;j<n;j++)
                            {
                                    if (mp[i][j]!='Y')
                                    {
                                            addedge(2+i+n*2,2+n+j+n*2,1);
                                    }else
                                    {
                                            addedge(2+i,2+j+n,1);
                                    }
                            }
                    }
                    ans=dinic();
                    if (ans!=mid*n)
                    {
                            r=mid;
                    }else
                    {
                            l=mid;
                    }
            }
            printf("%d
    ",l);
            return 0;
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    PDO 数据访问抽象层
    递归例子
    Windows对象操作:浏览器窗口信息
    练习题:选择器和选择好友
    搭建wamp环境,数据库基础知识
    堆表空间管理
    vc弹出USB的方法. 附试验通过的代码!
    javascript 调用C++函数
    [转]在Win7 64位注册ActiveX控件
    SetForegroundWindow的正确用法
  • 原文地址:https://www.cnblogs.com/mhy12345/p/3996066.html
Copyright © 2020-2023  润新知