假期的宿舍 二分图
Code:
#include<cstdio> #include<cstring> #include<vector> #include<queue> #include<algorithm> using namespace std; const int maxn=300; const int INF=1000000+233; int C[maxn][maxn],is[maxn],home[maxn],idx[maxn]; int s,t; struct Edge{ int from,to,cap; Edge(int u,int v,int c):from(u),to(v),cap(c){} }; struct Dicnic{ vector<Edge>edges; vector<int>G[maxn]; queue<int>Q; int d[maxn],vis[maxn],current[maxn]; void init() { edges.clear(); for(int i=0;i<maxn;++i)G[i].clear(); memset(d,0,sizeof(d)); memset(vis,0,sizeof(vis)); memset(current,0,sizeof(current)); } void add_edge(int u,int v,int c) { edges.push_back(Edge(u,v,c)); edges.push_back(Edge(v,u,0)); int m=edges.size(); G[u].push_back(m-2); G[v].push_back(m-1); } int BFS() { memset(vis,0,sizeof(vis)); Q.push(s);vis[s]=1,d[s]=0; while(!Q.empty()) { int u=Q.front();Q.pop(); int siz=G[u].size(); for(int i=0;i<siz;++i) { Edge r=edges[G[u][i]]; if(!vis[r.to]&&r.cap>0) { vis[r.to]=1,d[r.to]=d[u]+1; Q.push(r.to); } } } if(vis[t])return 1; return 0; } int dfs(int x,int cur) { if(x==t)return cur; int f,flow=0; int siz=G[x].size(); for(int i=current[x];i<siz;++i) { current[x]=i; int u=G[x][i]; Edge r=edges[u]; if(d[r.to]==d[x]+1&&r.cap>0) { f=dfs(r.to,min(cur,r.cap)); if(f>0) { cur-=f,flow+=f; edges[u].cap-=f,edges[u^1].cap+=f; } } if(cur==0)break; } return flow; } int maxflow() { int flow=0; while(BFS()) { memset(current,0,sizeof(current)); flow+=dfs(s,INF); } return flow; } }op; void init() { memset(is,0,sizeof(is)); memset(home,0,sizeof(home)); memset(C,0,sizeof(C)); } int main() { //freopen("in.txt","r",stdin); int T,n; scanf("%d",&T); while(T--) { op.init(); init(); int num=0,cc=0; scanf("%d",&n); for(int i=1;i<=n;++i) { int a;scanf("%d",&a); if(a) { is[i]=1,num+=1,idx[i]=num; } } for(int i=1;i<=n;++i) { int a;scanf("%d",&a); if(is[i]&&a)home[i]=1,cc+=1; } for(int i=1;i<=n;++i) for(int j=1;j<=n;++j)scanf("%d",&C[i][j]); s=0,t=188; for(int i=1;i<=n;++i) { if(is[i])op.add_edge(n+idx[i],t,1); if(!home[i]) { op.add_edge(s,i,1); if(is[i])op.add_edge(i,idx[i]+n,1); for(int j=1;j<=n;++j) { if(C[i][j]&&is[j])op.add_edge(i,n+idx[j],1); } } } int ans=op.maxflow(); if(ans==n-cc)printf("^_^\n"); else printf("T_T\n"); } return 0; }