BZOJ 1305: [CQOI2009]dance跳舞( 最大流 )

云神代码很短...0 ms过的...看了代码 , 大概是贪心... orz 我不会证

数据这么小乱搞就可以了吧... ←_←

这道题网络流还是可以写的...

既然限制了最多只能和 k 个不喜欢的人dance ,  那么就把每个人拆成 a , b 两个点 . 限制完了之后 , 因为 n <= 50 , 我们可以直接从从小到大枚举 , 一个一个增广 .

具体建图 :

boy_a( i ) -> boy_b( i ) ( cap : k ) , girl_b( i ) -> girl_a( i ) ( cap : k ) ( 1 <= i <= n )

对于两个人 boy( i ) , girl( j ) :

boy( i ) and girl( j ) are friends : boy_a( i ) -> girl_a( j ) ( 1 )

boy( i ) and girl( j ) aren‘t friends : boy_b( i ) -> girl_b( j ) ( 1 )

然后每次给 S -> boy_a( i ) , girl_a( i ) -> T ( 1 <= i <= n ) 加一条 1 的弧 , 跑一下看增加的流量是否为 n , 假如是就继续并将答案 + 1 , 不是就结束

-------------------------------------------------------------------------------------------------

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

#define rep( i , n ) for( int i = 0 ; i < n ; ++i )

#define clr( x , c ) memset( x , c , sizeof( x ) )

#define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )

using namespace std;

const int maxn = 200 + 10;

const int maxm = 20000;

const int inf = 1e8;

struct edge {

int to , cap;

edge *next , *rev;

} *pt , *head[ maxn ] , E[ maxm ];

inline void add( int u , int v , int d ) {

pt -> to = v;

pt -> cap = d;

pt -> next = head[ u ];

head[ u ] = pt++;

}

inline void add_edge( int u , int v , int d ) {

add( u , v , d );

add( v , u , 0 );

head[ u ] -> rev = head[ v ];

head[ v ] -> rev = head[ u ];

}

void edge_init() {

pt = E;

clr( head , 0 );

}

int h[ maxn ] , cnt[ maxn ];

edge *p[ maxn ] , *cur[ maxn ];

int N , S , T;

int maxFlow() {

clr( cnt , 0 ) , cnt[ 0 ] = N;

clr( h , 0 );

rep( i , N ) cur[ i ] = head[ i ];

int A = inf , x = S , flow = 0;

edge* e;

while( h[ S ] < N ) {

for( e = cur[ x ] ; e ; e = e -> next )

if( e -> cap && h[ x ] == h[ e -> to ] + 1 ) break;

if( e ) {

p[ e -> to ] = cur[ x ] = e;

A = min( A , e -> cap );

x = e -> to;

if( x == T ) {

for( ; x != S ; x = p[ x ] -> rev -> to ) {

p[ x ] -> cap -= A;

p[ x ] -> rev -> cap += A;

}

flow += A;

A = inf;

}

} else {

if( ! --cnt[ h[ x ] ] ) break;

h[ x ] = N;

for( e = head[ x ] ; e ; e = e -> next )

if( e -> cap && h[ e -> to ] + 1 < h[ x ] ) {

h[ x ] = h[ e -> to ] + 1;

cur[ x ] = e;

}

++cnt[ h[ x ] ];

if( x != S ) x = p[ x ] -> rev -> to;

}

}

return flow;

}

#define boy_a( i ) ( i )

#define girl_a( i ) ( i + ( n << 1 ) )

#define boy_b( i ) ( i + n )

#define girl_b( i ) ( i + n * 3 )

int main() {

freopen( "test.in" , "r" , stdin );

freopen( "test.out" , "w" , stdout );

edge_init();

int n , k;

char c;

cin >> n >> k;

S = 0 , T = 4 * n + 1 , N = T + 1;

Rep( i , n ) {

add_edge( boy_a( i ) , boy_b( i ) , k );

add_edge( girl_b( i ) , girl_a( i ) , k );

}

Rep( i , n )

Rep( j , n ) {

scanf( " %c" , &c );

if( c == ‘Y‘ )

add_edge( boy_a( i ) , girl_a( j ) , 1 );

else

add_edge( boy_b( i ) , girl_b( j ) , 1 );

}

int ans = 0;

for( ; ; ) {

Rep( i , n ) {

add_edge( S , boy_a( i ) , 1 );

add_edge( girl_a( i ) , T , 1 );

}

if( maxFlow() == n ) ans++;

else break;

}

cout << ans << "\n";

return 0;

}

-------------------------------------------------------------------------------------------------

1305: [CQOI2009]dance跳舞

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

加强数据By dwellings and liyizhen2

时间: 2024-10-21 21:34:44

BZOJ 1305: [CQOI2009]dance跳舞( 最大流 )的相关文章

bzoj 1305: [CQOI2009]dance跳舞

题目链接 bzoj 1305: [CQOI2009]dance跳舞 题解 男,女生拆点A1A2,B1B2,拆成两点间分别连容量为K的边,限制与不喜欢的人跳舞的数量 A1连接源点容量为x,B1连接汇点容量为x,x即为歌曲数目 对与相互喜欢的男女直在A1,B1间接连容量为1的边 对于相互不喜欢A2练到B2,容量为1 二分x的大小,每次重新构图,判断该图是否满流,慢流则说明该曲目可行 代码 #include<queue> #include<cstdio> #include<cstr

BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连一条流量为k的边.两个人若互相喜欢则点1之间连边,不喜欢则点2之间连边 对于每个要验证的x值 将每个人的点1向源或汇连一条流量为x的边 然后二分答案跑最大流就可以 #include<cstdio> #include<cstring> #include<iostream> #

BZOJ 1305 [CQOI2009]dance跳舞(二分+网络流)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1305 [题目大意] 一次舞会有n个男孩和n个女孩. 每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞. 每个男孩都不会和同一个女孩跳两首(或更多)舞曲. 有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”). 每个男孩最多只愿意和k个不喜欢的女孩跳舞, 而每个女孩也最多只愿意和k个不喜欢的男孩跳舞.给出每对男孩女孩是否相互喜欢的信息, 舞会最多能有几首舞曲? [题解] 我们

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

1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 1340  Solved: 581[Submit][Status] Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”).每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜

1305: [CQOI2009]dance跳舞

Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 4169  Solved: 1804[Submit][Status][Discuss] Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”).每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞.给出每对男孩女

【BZOJ 1305】 [CQOI2009]dance跳舞

1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 1586  Solved: 666 [Submit][Status] Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会"单向喜欢").每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只

BZOJ-1305: [CQOI2009]dance跳舞(最大流 增加超级源汇+分裂点+二分 水题)

1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec  Memory Limit: 162 MB Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”).每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞.给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲? Inpu

bzoj千题计划130:bzoj1305: [CQOI2009]dance跳舞

http://www.lydsy.com/JudgeOnline/problem.php?id=1305 每个人拆为喜欢(yes)和不喜欢(no)两个点 二分答案 1.每两个人之间只能跳一次 喜欢则 男yes i 向 女yes j 连流量为1的边 不喜欢则 男no i 向 女no j 连流量为1的边 2.最多与k个不喜欢的人跳 男yes i 向 男no i 连流量为 k的边 女no j 向 女yes j 连流量为k 的边 3. 源点向 男yes i 连流量mid 的边 女yes j 向汇点连流量

bzoj1305: [CQOI2009]dance跳舞(二分答案+网络流)

1305: [CQOI2009]dance跳舞 题目:传送门 题解: 一眼网络流基础建模...然后就GG了 二分答案+拆点建边+最大流判断: 把男女生拆为男1,男2,女1,女2 1.男1和男2还有女1和女2之间连边,流量为约束条件k 2.st连男1,女2连ed,流量为二分的mid 3.如果男生i喜欢女生j,就将男1与女2相连(不在约束条件内) 4.如果不喜欢,就将男2与女1相连(在约束条件内) 代码: 1 #include<cstdio> 2 #include<cstring> 3