BZOJ 1305--[CQOI2009]dance跳舞(最大流)
1305: [CQOI2009]dance跳舞
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4150 Solved: 1792
[Submit][Status][Discuss]
Description
一次舞会有n个男孩和n个女孩。每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首(或更多)舞曲。有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”)。每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞。给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲?
Input
第一行包含两个整数n和k。以下n行每行包含n个字符,其中第i行第j个字符为'Y'当且仅当男孩i和女孩j相互喜欢。
Output
仅一个数,即舞曲数目的最大值。
Sample Input
3 0
YYY
YYY
YYY
YYY
YYY
YYY
Sample Output
3
HINT
N<=50 K<=30
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=1305
Solution
最大流裸题。。。
将每个男孩和女孩拆成两个点,喜欢和不喜欢各自连边。。。
给不喜欢的连一条容量为k的边限一下流就可以了。。。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define N 500 #define LL long long #define inf 1000000000 using namespace std; inline LL Read(){ LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,k,S,T,cnt=1,ans=0,re=0; int hed[N],h[N],q[1000000]; char s[N]; struct edge{ int r,nxt,v; }e[1000000]; void insert(int u,int v,int w){ e[++cnt].r=v;e[cnt].nxt=hed[u];hed[u]=cnt;e[cnt].v=w; e[++cnt].r=u;e[cnt].nxt=hed[v];hed[v]=cnt;e[cnt].v=0; } bool bfs(){ int head=0,tail=1,now; memset(h,-1,sizeof(h)); h[S]=1;q[1]=S; while(head!=tail){ head++;now=q[head]; for(int i=hed[now];i;i=e[i].nxt) if(e[i].v&&h[e[i].r]==-1){ h[e[i].r]=h[now]+1; q[++tail]=e[i].r; } } return h[T]!=-1; } int dfs(int x,int F){ if(x==T) return F; int w,used=0; for(int i=hed[x];i;i=e[i].nxt) if(h[x]+1==h[e[i].r]){ w=F-used; w=dfs(e[i].r,min(e[i].v,w)); e[i].v-=w; e[i^1].v+=w; used+=w; if(used==F) return F; } if(!used) h[x]=-1; return used; } void dinic(){ while( bfs() ) ans+=dfs(S,inf); } void work(){ for(int i=1;i<=n;i++){ insert(S,i,1); insert(i+n*2,T,1); } ans=0; dinic(); if(ans==n){ re++; work(); } return; } int main(){ n=Read();k=Read(); S=0;T=n*4+1; for(int i=1;i<=n;i++){ insert(i,i+n,k);insert(i+n*3,i+n*2,k); } for(int i=1;i<=n;i++){ scanf("%s",s+1); for(int j=1;j<=n;j++){ if(s[j]=='Y') insert(i,j+n*2,1); else insert(i+n,j+n*3,1); } } work(); printf("%d\n",re); return 0; }
This passage is made by Iscream-2001.