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

原文地址:https://www.cnblogs.com/mhy12345/p/3996066.html