bzoj1305 [CQOI2009]dance跳舞
来源:互联网 发布:灭罪师类似的网络剧 编辑:程序博客网 时间:2024/05/08 04:43
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
先把每个人i拆分成ix和iy两个节点,ix连向喜欢的人,iy连向不喜欢的人,容量为1(比如如果男生i与女生j互相喜欢,则由ix连向jx,如果男生i与女生j互相不喜欢,则由iy连向jy),再将每个男生男生ix连向iy,容量为k;每个女生iy连向ix,容量为k。由源点向每个男生的x节点连上一条边,再由每个女生的x节点向汇点连上一条边,容量均为a。最后从小到大枚举a,计算最大流flow,若发现a*n>flow(不满流),则停止枚举,a-1即为答案。
(粘自hzwer,不要问我为什么,太懒)
#include <bits/stdc++.h>#define inf 0x7fffffff#define T 1001#define N 1010#define M 100010using namespace std;int head[N],q[N],h[N];int cnt,ans, cur[N], mid, mx;int n,k,mp[N][N];struct Edge{ int next, to, v;}e[M];inline int read(){ int 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;}void ins(int u, int v, int w){ e[++ cnt].next = head[u]; e[cnt].to = v; e[cnt].v = w; head[u] = cnt;}void insert(int u, int v, int w){ ins(u, v, w); ins(v, u, 0);}int bfs(){ int t = 0, w = 1; memset(h, -1, sizeof(h)); h[0] = 0; q[0] = 0; while(t != w) { int now = q[t ++]; if(t == M) t = 0; for(int i = head[now]; i; i = e[i].next) { int y = e[i].to; if(h[y] == -1 && e[i].v) { h[y] = h[now] + 1; q[w ++] = y; if(w == M) w = 0; } } } if(h[T] == -1) return 0; else return 1;}int dfs(int x, int f){ if(x == T) return f; int used = 0, w; for(int i = head[x]; i; i = e[i].next) { int y = e[i].to; if(h[y] == h[x] + 1 && e[i].v) { w = dfs(y, min(f - used, e[i].v)); e[i].v -= w; used += w; //if(e[i].v) cur[x] = i; e[i ^ 1].v += w; if(f == used) return used; } } if(used == 0) h[x] = -1; return used;}void dinic(){ while(bfs()) { //for(int i = 0; i <= T; i ++) //a cur[i] = head[i]; ans += dfs(0, inf); }}void Init(){ n = read(); k = read(); for(int i = 1; i <= n; i ++) { char ch[51]; scanf("%s",ch); for(int j = 1; j <= n; j ++) if(ch[j - 1] == 'Y')mp[i][j] = 1; }}void build(){ cnt = 1; memset(head,0,sizeof(head)); for(int i = 1; i <= n; i ++)insert(0, i, mid); for(int i = 1; i <= n; i ++)insert(i, i + 500, k); for(int i = 1; i <= n; i ++)insert(n + i + 500, n + i, k); for(int i = 1; i <= n; i ++)insert(n + i, T, mid); for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) if(mp[i][j]) insert(i, n + j, 1); else insert(i + 500, n + j + 500, 1);}int main(){ Init(); int l = 0, r = 50; while(l <= r) { mid = (l + r) >> 1; build(); ans = 0; dinic(); if(ans >= n * mid) {mx = mid; l = mid + 1;} else r = mid - 1; } printf("%d",mx); return 0;}
0 0
- BZOJ1305 [CQOI2009]dance跳舞
- bzoj1305【CQOI2009】dance 跳舞
- bzoj1305[CQOI2009]dance跳舞
- bzoj1305: [CQOI2009]dance跳舞
- bzoj1305 [CQOI2009]dance跳舞
- 【bzoj1305】【CQOI2009】【dance】【跳舞】
- BZOJ1305: [CQOI2009]dance跳舞
- bzoj1305 [CQOI2009]dance跳舞
- bzoj1305[CQOI2009]dance跳舞
- bzoj1305: [CQOI2009]dance跳舞
- 【bzoj1305】[CQOI2009]dance跳舞
- bzoj1305: [CQOI2009]dance跳舞
- bzoj1305 [CQOI2009]dance跳舞
- BZOJ1305: [CQOI2009]dance跳舞
- BZOJ1305 [CQOI2009]dance跳舞
- bzoj1305 [CQOI2009]dance跳舞 最大流 二分
- 【bzoj1305】[CQOI2009]dance跳舞 最大流
- 【BZOJ1305】[CQOI2009]dance跳舞【最大流】【二分】
- ScrollView嵌套ListView高度计算
- ArrayList
- 轻松搞定左外连接、右外连接、内连接、全连接、交叉连接
- matlab数值积分技巧之将符号表达式转化为函数句柄
- 嵌入式linux:linux tee 命令详解
- bzoj1305 [CQOI2009]dance跳舞
- Android系统--视图绘制 (View Render)
- 1999年世界卫生组织/国际高血压联盟关于高血压治疗指南
- oracle仅部分记录建立索引的方法
- 递归法累计求和
- 关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析
- libsvm Minist Hog 手写体识别
- 欢迎使用CSDN-markdown编辑器
- MySQL索引类型一览 让MySQL高效运行起来