假期的宿舍 洛谷2055 网络流
来源:互联网 发布:linux os update 编辑:程序博客网 时间:2024/04/30 04:41
题目大意
学校放假了。。。有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题。比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识。我们假设每个人只能睡和自己直接认识的人的床。那么一个解决方案就是 B 睡 A 的床而 C 睡 B 的床。而实际情况可能非常复杂,有的人可能认识好多在校学生,在校学生之间也不一定都互相认识。我们已知一共有 n 个人,并且知道其中每个人是不是本校学生,也知道每个本校学生是否回家。问是否存在一个方案使得所有不回家的本校学生和来看他们的其他人都有地方住。
分析
网络流模板题
将一个人拆成两个点,一个是人,一个床。
如果两个人认识,且一个人有床,就连一条容量为一的边。
再将源点与需要床的人连边,将床与汇点连边。
最后跑网络流。
ps:好久没打,错了好多低级错误。。。
code
#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<queue>using namespace std;struct arr{ int x,y,w,next;}edge[1000];int ls[1000],cur[1000];int f[1000];int edge_m=1;int n,m,s,t;int ans,num=0;void add(int x,int y,int w){ edge[++edge_m]=(arr){x,y,w,ls[x]}; cur[y]=ls[x]=edge_m; f[edge_m]=w; edge[++edge_m]=(arr){y,x,w,ls[y]}; cur[y]=ls[y]=edge_m; f[edge_m]=0;}int dis[1000];bool bfs(){ memset(dis,-1,sizeof(dis)); queue<int> q; q.push(s); dis[s]=0; do{ int x=q.front(); q.pop(); for (int i=ls[x];i!=0;i=edge[i].next) { if ((f[i])&&(dis[edge[i].y]==-1)) { dis[edge[i].y]=dis[x]+1; q.push(edge[i].y); if (edge[i].y==t) return true; } } }while (!q.empty()); return false;}int find(int x,int min_){ if (x==t) return min_; int rec=min_; for (int &i=cur[x];i!=0;i=edge[i].next) { if ((f[i])&&(dis[edge[i].y]==dis[x]+1)) { int k=find(edge[i].y,min(min_,f[i])); f[i]-=k; f[i^1]+=k; rec-=k; if (rec==0) return min_; } } if (rec==min_) dis[x]=-1; return min_-rec;}int dinic(){ ans=0; while (bfs()) { for (int i=s;i<=t;i++) cur[i]=ls[i]; ans+=find(s,20000000); }}int a[1000],b[1000];int ll;int main(){ int T; scanf("%d",&T); while (T--) { edge_m=1; num=0; memset(ls,0,sizeof(ls)); memset(cur,0,sizeof(cur)); memset(edge,0,sizeof(edge)); memset(f,0,sizeof(f)); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=n;i++) scanf("%d",&b[i]); s=0; t=2*n+1; for (int i=1;i<=n;i++) { if (a[i]==0) add(s,i,1),num++; if ((a[i]==1)&&(b[i]==0)) add(s,i,1),num++; } for (int i=1;i<=n;i++) { if (a[i]==1) add(i+n,t,1); } ll=0; for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) { scanf("%d",&ll); if (ll==1) { add(i,j+n,1); } } } for (int i=1;i<=n;i++) { add(i,i+n,1); } dinic(); if (ans==num) printf("^_^\n"); else printf("T_T\n"); } return 0;}
阅读全文
0 0
- 假期的宿舍 洛谷2055 网络流
- 洛谷 2055 假期的宿舍
- 网络流[ZJOI2009] 假期的宿舍
- 【洛谷2055】【CJOJ2487】【ZJOI2009】 假期的宿舍
- bzoj 1433 假期的宿舍(网络流)
- bzoj 1433: [ZJOI2009]假期的宿舍 网络流
- BZOJ1433 / ZJOI2009 假期的宿舍【网络流/二分图匹配】
- 洛谷 P2055 假期的宿舍
- [洛谷P2055]假期的宿舍
- 洛谷2055 [ZJOI2009]假期的宿舍(二分图)
- 洛谷 P2055 [ZJOI2009]假期的宿舍
- 洛谷 P2055 [ZJOI2009] 假期的宿舍
- 洛谷 P2055 [ZJOI2009]假期的宿舍
- 洛谷P2055 [ZJOI2009]假期的宿舍
- BZOJ1433 假期的宿舍(最大流)
- 【BZOJ1433】【codevs2347】假期的宿舍,最大流
- BZOJ1433假期的宿舍
- [ZJOI2009]假期的宿舍
- 了解C语言之数组
- Sencha Touch Ext.Carousel 切换 Bug
- 用代理,拨号换IP
- python with和上下文管理工具
- 了解C语言之指针(一)
- 假期的宿舍 洛谷2055 网络流
- Python--套接字
- 借教室 洛谷1083 差分+二分
- 了解C语言之指针(二)
- 数组的使用
- 快速傅里叶变换(FFT)的原理及公式
- 如何求数组中的最大值
- 了解C语言之指针(三)
- 【最短路入门专题1】H