[bzoj 1305&1433]最大流练习题

来源:互联网 发布:纸模软件 编辑:程序博客网 时间:2024/06/14 01:06

1305: [CQOI2009]dance跳舞

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


这两题的难点就难在建图 建图过程详见代码注释

对于dfs的写法稍有改变 如按照原模板会超时。。。

借鉴hzwer的写法


//http://www.lydsy.com/JudgeOnline/problem.php?id=1305#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#define inf 0x7fffffffusing namespace std;int n,k,cnt=1;int start=0,end=1001;int ans;int mp[1005][1005],head[1005],d[1005];struct edge{int to,w,next;}e[500001];int mid;void ini(int x,int y,int z){e[++cnt].to=y;e[cnt].w=z;e[cnt].next=head[x];head[x]=cnt;}void insert(int x,int y,int z){ini(x,y,z);ini(y,x,0);}queue<int>q;bool bfs(){memset(d,-1,sizeof(d));d[start]=0;q.push(start);while(!q.empty()){int k=q.front();q.pop();for(int i=head[k];i;i=e[i].next){int kk=e[i].to;if(d[kk]==-1&&e[i].w>0){d[kk]=d[k]+1;q.push(kk);}}}if(d[end]==-1) return false;return true;}int dfs(int x,int f){    if(x==end)return f;    int w,used=0,i;    i=head[x];    while(i)    {            if(e[i].w&&d[e[i].to]==d[x]+1)            {                w=f-used;                w=dfs(e[i].to,min(w,e[i].w));                e[i].w-=w;                e[i^1].w+=w;                used+=w;                if(used==f)return f;            }            i=e[i].next;    }    if(!used) d[x]=-1;    return used;}int dinic(){while(bfs()){int a;if(a=dfs(0,inf))ans+=a;}}void build(){cnt=1;memset(head,0,sizeof(head));for(int i=1;i<=n;i++) insert(start,i,mid);//超级源和男的入点连for(int i=1;i<=n;i++) insert(i,i+500,k);//男的入点连出点for(int i=1;i<=n;i++) insert(i+n+500,i+n,k);//女 出点连入点for(int i=1;i<=n;i++) insert(i+n,end,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(){//freopen("rand.txt","r",stdin);scanf("%d%d",&n,&k);char s[100];for(int i=1;i<=n;i++){scanf("%s",s+1);for(int j=1;j<=n;j++){if(s[j]=='Y')mp[i][j]=1;}}int l=0,r=50;int mx=0;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;}

1433: [ZJOI2009]假期的宿舍

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2927  Solved: 1237
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0

Sample Output

ˆ ˆ

HINT

对于30% 的数据满足1 ≤ n ≤ 12。
对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。

Source

//http://www.lydsy.com/JudgeOnline/problem.php?id=1433//拆点 把人和床分开 1-n是人 1+n-2*n是床 //床和汇点连 源点连要床的人 每个人和能睡的床连 #include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#include<queue> #define inf 0x7fffffusing namespace std;int d[105],head[105],n,cnt=1,school[105],ans,tot;int start=0,end=101;struct edge{int to,next,w;}e[50005];void ini(int x,int y,int z){e[++cnt].to=y;e[cnt].w=z;e[cnt].next=head[x];head[x]=cnt;}void insert(int x,int y,int z){ini(x,y,z);ini(y,x,0);}queue<int>q;bool bfs(){q.push(start);memset(d,-1,sizeof(d));d[start]=0;while(!q.empty()){int k=q.front();q.pop();for(int i=head[k];i;i=e[i].next){int kk=e[i].to;if(d[kk]==-1&&e[i].w>0){d[kk]=d[k]+1;q.push(kk);}}}if(d[end]==-1) return false;return true;}int dfs(int x,int f){if(x==end) return f;int a,used=0;for(int i=head[x];i;i=e[i].next){int k=e[i].to;if(d[k]==d[x]+1&&e[i].w>0){a=f-used;a=dfs(k,min(a,e[i].w));e[i].w-=a;e[i^1].w+=a;used+=a;if(used==f) return f; }}if(!used) d[x]=-1;return used;} void dinic(){while(bfs())ans+=dfs(start,inf);}int main(){int T;scanf("%d",&T);while(T--){ans=tot=0;cnt=1;memset(head,0,sizeof(head));scanf("%d",&n);int temp;for(int i=1;i<=n;i++){scanf("%d",&school[i]);if(temp==1)insert(i+n,end,1);//住校代表有床 床连汇点 }int x;for(int i=1;i<=n;i++){scanf("%d",&x);if((school[i]&&!x)||!school[i]){//源点连需要床的人 insert(start,i,1);tot++;}}for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){scanf("%d",&x);if(x||i==j) insert(i,j+n,1);//人连能睡的床 }dinic();if(ans==tot)puts("^_^");        else puts("T_T");}return 0;} 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我想成为安利的员工怎么办会员 安利皇后锅锅盖吸在桌子上怎么办 淘宝客服退款返佣金诈骗后怎么办 第一试用网的钱提现出现问题怎么办 一个手机号注册两个京东账号怎么办 白色衣服被洗衣粉泡白了怎么办 白色衣服染成一块块荧光色了怎么办 中脉远红镇痛护腰不会发热了怎么办 用完悦诗风吟脸变黑不均匀怎么办 护肤品开封后一年还没用完怎么办 兰蔻化妆品套装正品和假怎么办 月经期间卫生巾搞得屁股疼怎么办 大姨妈特别多用卫生巾老是漏怎么办 夏天用卫生巾不透气摩擦红了怎么办 在日本的洗手间用完的姨妈巾怎么办 想穿短裙但是膝盖怕凉怎么办 裤子被卫生巾粘住扯不下来怎么办 医生说来姨妈不可以用卫生巾怎么办 隆胸以后摸起来感觉假体会动怎么办 产后15个月说恶露没排干净怎么办 母猪产后两天肚子里还有小猪怎么办 背心式无痕运动文胸显得胸小怎么办 卫生巾过敏起疙瘩反复挠不好怎么办 去健身房办卡老板跑了怎么办 买货我已经拒收商家不退款怎么办 在京东买了东西拒收不退款怎么办 罗马仕充电宝进入休眠状态怎么办 广发信用卡寄到家没拿到快递怎么办 包邮商家要买家出物流费怎么办? 美团外卖下单转化率低怎么办 京东退款不小心点了取消退款怎么办 近邻宝开了箱又关了怎么办 近邻宝箱子打开了东西忘记拿怎么办 京东取消订单商家总不取消怎么办 京东快递退货取件一直取不到怎么办 在京东线上付款了但没收到货怎么办 寄快递收件人电话号码写错了怎么办 京东购物实名认证被别人占用怎么办 货已发出单号还没填买家退货怎么办 自提柜还有一个包忘记拿怎么办 当顾客说衣服太贵的时候怎么办