BZOJ-1433 假期的宿舍 最大流+基础建图
2016-01-05 20:50
246 查看
网络流练习ing。。
1433: [ZJOI2009]假期的宿舍
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1748 Solved: 765
[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 Outpu**t
ˆ-ˆ
HINT
对于30% 的数据满足1 ≤ n ≤ 12。
对于100% 的数据满足1 ≤ n ≤ 50,1 ≤ T ≤ 20。
基础建图: 超级源连向所有在校生(有床位的人);所有在校生且不回家的,与所有非在校生的与超级源相连;每个点分成两个i与i',如果i和j认识连i与j';边权全部为1 最大流即为答案。
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define M 1000010 struct data{ int to,next,v; }edge[M]; int head[M],cnt=1; int dis[M]; int q[M],h,t; int c,n,ans,num; int zx[60],know[60][60],hj[60]; //zx【】是否在校,know【】【】是否认识,hj【】是否回家 void add(int u,int v,int w) { cnt++; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].v=w; } void make()//超级源为0,超级汇为2*n+1 { cnt=1; memset(head,0,sizeof(head)); num=0; for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) if (know[i][j]==1) { add(i,j+n,1); add(j+n,i,0); } for (int i=1; i<=n; i++) { if (zx[i]==1) { add(0,i,1); add(i,0,0); } if ((zx[i]==1 && hj[i]==0) || (zx[i]==0)) { add(i+n,2*n+1,1); add(2*n+1,i+n,0); num++;//需要床位数 } } } bool bfs() { memset(dis,-1,sizeof(dis)); q[1]=0; dis[0]=1; h=0; t=1; while (h<t) { int j=q[++h],i=head[j]; while (i) { if (edge[i].v>0 && dis[edge[i].to]<0) { dis[edge[i].to]=dis[j]+1; q[++t]=edge[i].to; } i=edge[i].next; } } if (dis[2*n+1]>0) return true; else return false; } int dfs(int loc,int low) { int flow=0; if (loc==2*n+1) return low; int i=head[loc]; while (i) { if (edge[i].v>0 && dis[edge[i].to]==dis[loc]+1 && (flow=dfs(edge[i].to,min(low,edge[i].v)))) { edge[i].v-=flow; edge[i^1].v+=flow; return flow; } i=edge[i].next; } return 0; } int main() { scanf("%d",&c); while (c--) { scanf("%d",&n); memset(zx,0,sizeof(zx)); memset(hj,0,sizeof(hj)); memset(know,0,sizeof(know)); for (int i=1; i<=n; i++) scanf("%d",&zx[i]); for (int i=1; i<=n; i++) scanf("%d",&hj[i]); for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) scanf("%d",&know[i][j]); for (int i=1; i<=n; i++) know[i][i]=1;//由题意自己和自己在读入时为不能睡,但实际可以,修改。 make(); ans=0; while (bfs()) { int now=0; while ((now=dfs(0,0x7fffffff))) ans+=now; } if (num==ans) puts("^_^"); else puts("T_T"); } return 0; }
相关文章推荐
- 代理模式
- Yii的日志的处理机制以及扩展案例
- 从小米想到的商业模式创新
- Java 字符串索引indexOf
- BZOJ-1433 假期的宿舍 最大流+基础建图
- WPS与matlab安装后直接命令行启动设置
- json和object之间相互转换
- Java+Servlet+filter+javascript+html+jsp登入注册更新个人信息
- 写点工作两年的一些感想吧
- hadoop原理?一?
- 【Unity开发】UNITY实现断点续传
- linux 下的phpstudy 添加 mysql 为环境变量
- Qt Creator下载和安装(详细教程)
- struts的过滤器代码
- 13. Roman to Integer leetcode Python 2016 new Season
- 使用SBT构建Scala项目
- Android摄像头基础
- 拦截器
- HDU1002 A + B Problem II
- Unity不规则碰撞