bzoj1433 [ZJOI2009]假期的宿舍 最大流

时间:2023-03-09 17:44:00
bzoj1433 [ZJOI2009]假期的宿舍 最大流

[ZJOI2009]假期的宿舍

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3429  Solved: 1459
[Submit][Status][Discuss]

Description

bzoj1433 [ZJOI2009]假期的宿舍 最大流

Input

bzoj1433 [ZJOI2009]假期的宿舍 最大流

Output

bzoj1433 [ZJOI2009]假期的宿舍 最大流

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。

源点向所有有床位的连边

需要床位的向汇点连边

如果i可以睡j的床

i向j‘连边

 #include<iostream>
#include<cstring>
#include<cstdio>
#define T 101
#define inf 0x7fffffff
using namespace std;
int sc[];
int n,tot,cnt=,ans,head[],h[];
struct data{int to,next,v;}e[];
void ins(int u,int v,int w)
{cnt++;e[cnt].to=v;e[cnt].v=w;e[cnt].next=head[u];head[u]=cnt;}
void insert(int u,int v,int w)
{ins(u,v,w);ins(v,u,);}
bool bfs()
{
int q[],t=,w=,i,now;
memset(h,-,sizeof(h));
q[]=h[]=;
while(t!=w)
{
now=q[t];t++;if(t==)t=;
i=head[now];
while(i)
{
if(e[i].v&&h[e[i].to]<)
{h[e[i].to]=h[now]+;q[w++]=e[i].to;if(w==)w=;}
i=e[i].next;
}
}
if(h[T]==-)return ;
return ;
}
int dfs(int x,int f)
{
if(x==T)return f;
int i=head[x],w,used=;
while(i)
{
if(e[i].v&&h[e[i].to]==h[x]+)
{
w=f-used;
w=dfs(e[i].to,min(w,e[i].v));
e[i].v-=w;
e[i^].v+=w;
used+=w;
if(used==f)return f;
}
i=e[i].next;
}
if(!used)h[x]=-;
return used;
}
void dinic(){while(bfs())ans+=dfs(,inf);}
int main()
{
int test;scanf("%d",&test);
while(test--)
{
tot=ans=;cnt=;
memset(head,,sizeof(head));
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&sc[i]);
if(sc[i])
insert(i+n,T,);//如果是在校学生,则有床位
}
int x;
for(int i=;i<=n;i++)
{
scanf("%d",&x);
if((sc[i]&&!x)||!sc[i])
{
insert(,i,);//不回家或者外校的需要床
tot++;
}
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
scanf("%d",&x);
if(x||i==j)insert(i,j+n,);//可以睡的床
}
dinic();
if(ans==tot)puts("^_^");
else puts("T_T");
}
return ;
}