[bzoj 1305&1433]最大流练习题
来源:互联网 发布:纸模软件 编辑:程序博客网 时间:2024/06/14 01:06
1305: [CQOI2009]dance跳舞
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 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
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 MBSubmit: 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
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;}
阅读全文
1 0
- [bzoj 1305&1433]最大流练习题
- bzoj 1305 二分+最大流
- BZOJ 1305: [CQOI2009]dance跳舞 最大流
- BZOJ 1066 最大流
- bzoj 1066 最大流
- bzoj 1458 最大流
- bzoj 1711 最大流
- BZOJ 3931 最大流
- BZOJ 4514 浅谈最大费用最大流
- bzoj 2661(最大费用流)
- bzoj 1532(二分+最大流)
- bzoj 3931(spfa+最大流)
- bzoj 1066 蜥蜴(最大流)
- bzoj 1066 蜥蜴 最大流
- BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流
- BZOJ-1305 dance跳舞 建图+最大流+二分判定
- bzoj 1305: [CQOI2009]dance跳舞(二分+最大流)
- BZOJ 1305: [CQOI2009]dance跳舞 多重匹配,网络最大流
- 写一个简单的webserver
- 对于《第一行代码》中的RecyclerView中的一个列表间距太远(占据一个界面)的问题
- CENTOS7 snort 轻量级入侵检测系统安装与使用
- Unity Shader之Blending
- MongoDB--数据库管理
- [bzoj 1305&1433]最大流练习题
- Unity3d BoxCollider线框绘制工具
- md5`加密2:udf简单实现
- Hibernate事务中四种状态
- YII设置别名 'Unable to resolve the request "site/error".'
- mysql 索引类型以及创建
- SSM个人博客项目实战01
- 78_游戏项目_图片的加载
- ubuntu /var/log/下各个日志文件