1433: [ZJOI2009]假期的宿舍

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3371  Solved: 1425
[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。

我的方法跟网上其他博客有点不一样,随便YY的。把每个人拆成2个点ai bi,建立超级源汇S,T。

  (1)S向所有 外校人员的ai建立容量1的边

  (2)所有 在校的要回家的学生的bi向T连容量为1的边

  (3)对于一对相互认识的人bi->aj互相建容量无穷边

  (4)每个人的ai向bi建立容量1的边

  这样以后一个流就表示一个挪动方案

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#define inf 0x3f3f3f3f
#define ll long long
#define N 105
using namespace std;
int n,S,T,tot,cur[N],st[N],hd[N],gh[N],kn[N][N],d[N],vis[N];
struct edge{int v,next,cap,flow;}e[N*N*4];
void adde(int u,int v,int c){
e[tot].v=v;
e[tot].next=hd[u];
e[tot].cap=c;
e[tot].flow=0;
hd[u]=tot++;
} bool bfs(){
queue<int>q;
memset(vis,0,sizeof(vis));
q.push(S);d[S]=0;
while(!q.empty()){
int u=q.front();q.pop();vis[u]=1;
for(int i=hd[u];~i;i=e[i].next){
int v=e[i].v;
if(e[i].cap<=e[i].flow||vis[v])continue;
d[v]=d[u]+1;q.push(v);
}
}
return vis[T];
} int dfs(int u,int a){
if(u==T||!a)return a;
int fl=0,f;
for(int i=hd[u];~i;i=e[i].next){
int v=e[i].v;
if(d[v]==d[u]+1&&(f=dfs(v,min(e[i].cap-e[i].flow,a)))){
fl+=f;a-=f;
e[i].flow+=f;
e[i^1].flow-=f;
if(a<=0)break;
}
}
return fl;
}
int main(){
#ifdef wsy
freopen("data.in","r",stdin);
#else
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
#endif
int cas;scanf("%d",&cas);
while(cas--){
scanf("%d",&n);S=0;T=2*n+1;tot=0;
memset(hd,-1,sizeof(hd));
for(int i=1;i<=n;i++)scanf("%d",&st[i]); // for(int i=1;i<=n;i++)if(!st[i])printf("%d ",i);puts(""); for(int i=1;i<=n;i++)scanf("%d",&gh[i]); // for(int i=1;i<=n;i++)if(st[i]&&gh[i])printf("%d ",i);puts(""); for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&kn[i][j]);
for(int i=1;i<=n;i++){
if(st[i]){
if(gh[i])adde(i+n,T,1),adde(T,i+n,0);
}
else adde(S,i,1),adde(i,S,0);
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
if(!kn[i][j])continue;
// printf("%d %d\n",i,j);
int f1=st[i],f2=st[j];
if(f1)adde(j+n,i,inf),adde(i,j+n,0);
if(f2)adde(i+n,j,inf),adde(j,i+n,0);
}
for(int i=1;i<=n;i++)
adde(i,i+n,1),adde(i+n,i,0);
while(bfs()){
for(int i=S;i<=T;i++)cur[i]=hd[i];
dfs(S,0x3f3f3f3f);
}
int fg=0;
for(int i=hd[S];~i;i=e[i].next)
if(e[i].cap-e[i].flow>0)fg=1;
if(fg)puts("T_T");
else puts("^_^");
}
return 0;
}

  

最新文章

  1. 【bzoj4423】 AMPPZ2013—Bytehattan
  2. 从多列的DataTable里取需要的几列(转)
  3. 鸟哥的linux私房菜学习记录之程序管理和SElinux初探
  4. 编写自己的Windows Live Writer插件
  5. 查看linux进程(强制中止进程),服务及端口号,
  6. POJ1087 A Plug for UNIX 【最大流】
  7. sql server 2008 数据库管理系统使用SQL语句创建登录用户详细步骤
  8. ansible 批量安装zabbix agentd客户端
  9. 1016. Phone Bills (25) -vector排序(sort函数)
  10. MR for Baum-Welch algorithm
  11. 在docker私有仓库如何查看有哪些镜像?
  12. Android -- ConditionVariable
  13. Lemon OA第2篇:功能解析方法
  14. Zookeeper 系列(一)基本概念
  15. 轻松实现Ecshop商城多语言切换
  16. JAVA消息 AMQP
  17. selenium,unittest——驾照科目一网上答题自动化
  18. Git 分支管理-git stash 和git stash pop
  19. VirtualBox 安装XP虚拟机, 安装DB2
  20. Cg(c for graphic)语言的数据类(转)

热门文章

  1. html{font-size:62.5%}
  2. APP手机端加载不到资源服务器后台解决参考
  3. 第四章 JavaScript操作DOM对象
  4. ELK学习总结(1-2)安装ElasticSearch
  5. 九、Python+Selenium模拟用QQ登陆腾讯课堂,并提取报名课程(练习)
  6. Django中自定义过滤器的使用
  7. linux搭建django项目基本步骤
  8. H5的canvas绘图技术
  9. 优易软件-关于click事件在苹果手机失效的问题
  10. vue-router动态路由 刷新页面 静态资源没有加载的原因