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。
网络流
每个学生拆点
原点向每个在校的连边(就是有床的)
汇点向每个需要床的连边(就是不在校的或者在校且没有回家的)
如果i、j认识,互相连边
然后dinic。没了
要注意i可以睡自己的床
#include<cstdio> #include<cstring> #define S 0 #define T 1001 #define inf 0x7fffffff struct edge{ int to,next,v; }e[5001]; int head[5001],h[5001]; int q[20001]; int n,cnt,ans; inline int min(int a,int b){return a<b?a:b;} inline void ins(int u,int v,int w) { e[++cnt].to=v; e[cnt].next=head[u]; e[cnt].v=w; head[u]=cnt; } inline void insert(int u,int v,int w) { ins(u,v,w); ins(v,u,0); } inline int read() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } bool school[1001]; inline bool bfs() { memset(h,-1,sizeof(h)); int t=0,w=1; q[1]=S;h[S]=0; while (t<w) { int now=q[++t]; for (int j=head[now];j;j=e[j].next) { if (e[j].v&&h[e[j].to]==-1) { q[++w]=e[j].to; h[e[j].to]=h[now]+1; } } } if (h[T]==-1) return 0; return 1; } inline int dfs(int x,int f) { if (x==T||f==0) return f; int w,used=0; for (int i=head[x];i;i=e[i].next) { if (e[i].v&&h[e[i].to]==h[x]+1) { w=used; w=dfs(e[i].to,min(e[i].v,f-used)); e[i].v-=w; e[i^1].v+=w; used+=w; if (used==f) return f; } } if (!used) h[x]==-1; return used; } inline void dinic() {while (bfs()) ans-=dfs(S,inf);} inline void work() { ans=0;cnt=1; memset(e,0,sizeof(e)); memset(head,0,sizeof(head)); n=read(); for (int i=1;i<=n;i++) { school[i]=read(); if (school[i])insert(i+n,T,1); } for (int i=1;i<=n;i++) { int x=read(); if (!school[i]||(school[i]&&!x)) { insert(S,i,1); ans++; } } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { int x=read(); if (i==j||x)insert(i,j+n,1); } dinic(); if (ans==0) printf("^_^ "); else printf("T_T "); } int main() { int t=read(); while (t--)work(); }