博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[ZJOI2009]假期的宿舍(luogu P2055)
阅读量:5018 次
发布时间:2019-06-12

本文共 1792 字,大约阅读时间需要 5 分钟。

原题链接:https://www.luogu.org/problem/show?pid=2055

其实本题除了建边之外几乎与二分图最大匹配模板题没什么区别。

二分图的一边的人,一边为床。。。

如果本校学生且回家,那么就没他什么事情了,他并不需要床铺。如果是本校学生但不回家,那么就可以向自己的床连一条边,因为下面的邻接矩阵中并没有给出这种方案,但它是存在的。外校学生的话,就要向自己认识的人的床连一条边。

之后跑二分图最大匹配即可,检查匹配数是否能满足需求。

本题有多组数据,一定记得把head,tot,cnt这些东西清空。不然就会像我在后面的几组数据中WA到怀疑人生。

 

#include
#include
void read(int &y){ y=0;char x=getchar(); while(x<'0'||x>'9') x=getchar(); while(x>='0'&&x<='9') { y=y*10+x-'0'; x=getchar(); }}struct edge{ int u,v;}e[10005];int t,n,tot,sum,x,cnt;int d[55],z[55];int vis[105],head[105],match[105];void add(int u,int v){ e[++cnt].u=head[u]; e[cnt].v=v; head[u]=cnt;}int dfs(int x){ for(int i=head[x];i;i=e[i].u) { int t=e[i].v; if(vis[t]==1) continue; vis[t]=1; if(match[t]==0||dfs(match[t])) { match[t]=x; return 1; } } return 0;}int main(){ read(t); while(t--) { read(n); memset(head,0,sizeof(head));cnt=0;tot=0;//WA WA WA for(int i=1;i<=n;i++) read(d[i]); for(int i=1;i<=n;i++) { read(z[i]); if(z[i]==0&&d[i]==1) add(i,i); if(d[i]==0||(z[i]==0&&d[i]==1)) tot++; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { read(x); if(x==1&&d[j]==1) add(i,j); } } memset(match,0,sizeof(match)); sum=0; for(int i=1;i<=n;++i) { if((d[i]==1&&z[i]==0)||d[i]==0) { memset(vis,0,sizeof(vis)); if(dfs(i)) sum++; } } if(sum>=tot) printf("^_^\n"); else printf("T_T\n"); } return 0;}

 

转载于:https://www.cnblogs.com/zeroform/p/7722102.html

你可能感兴趣的文章