bzoj1305: [CQOI2009]dance跳舞

拆点。。。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define qwq(x) for(edge *o=head[x];o;o=o->next)
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x;
}
const int nmax=300;
const int maxn=100000;
const int inf=0x7f7f7f7f;
struct edge{
	int to,cap;edge *next,*rev;
};
edge edges[maxn],*pt,*head[nmax],*cur[nmax],*p[nmax];
int cnt[nmax],h[nmax];
char c[100];
void add(int u,int v,int w){
	pt->to=v;pt->cap=w;pt->next=head[u];head[u]=pt++;
}
void adde(int u,int v,int w){
	add(u,v,w);add(v,u,0);head[u]->rev=head[v];head[v]->rev=head[u];
}
int maxflow(int s,int t,int n){
	clr(cnt,0);clr(h,0);cnt[0]=n;
	int flow=0,a=inf,x=s;edge *e;
	while(h[s]<n){
		for(e=cur[x];e;e=e->next) if(e->cap>0&&h[e->to]==h[x]-1) break;
		if(e){
			p[e->to]=cur[x]=e;a=min(a,e->cap);x=e->to;
			if(x==t){
				while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to;
				flow+=a,a=inf;
			}
		}else{
			if(!--cnt[h[x]]) break;
			h[x]=n;
			for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e;
			cnt[h[x]]++;
			if(x!=s) x=p[x]->rev->to;
		}
	}
	return flow;
}
int main(){
	pt=edges;clr(head,0);
	int n=read(),k=read(),s=0,t=n+n+n+n+1,N=t+1;
	rep(i,n) {
	   scanf("%s",c);
	   rep(j,n) {
		if(c[j-1]=='Y') adde(i,n+n+n+j,1);
		else adde(n+i,n+n+j,1);
	   }
    }
	rep(i,n) adde(i,n+i,k),adde(n+n+i,n+n+n+i,k),adde(s,i,1),adde(n+n+n+i,t,1);
	int ans=0;
	while(1){
		if(maxflow(s,t,N)!=n) break;
		ans++;
		rep(i,n)  adde(s,i,1),adde(n+n+n+i,t,1);
	}
	printf("%d
",ans);
	return 0;
}

 

1305: [CQOI2009]dance跳舞

Time Limit: 5 Sec  Memory Limit: 162 MB
Submit: 2627  Solved: 1082
[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

Sample Output

3

HINT

N<=50 K<=30

Source

[Submit][Status][Discuss]

 

原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5659890.html