bzoj1433: [ZJOI2009]假期的宿舍(二分图匹配)

来源:互联网 发布:展会erp系统源码 编辑:程序博客网 时间:2024/05/16 03:24

题目传送门
有点恶心。

解法:
二分图匹配直接上。
如果你在校而且不回家,那么自己可以睡自己的床。
如果你认识的人在校,那么你可以睡他的床。
跑一遍最大匹配。。

话说题目描述好像有点问题吧。。
怎么A和B是在校学生B就可以睡A的床了。。
搞得我一开始以为在校的都互相认识。
WA无限。

代码实现:

#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>using namespace std;struct node {int x,y,next;}a[110000];int len,last[11000];void ins(int x,int y) {len++;a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;}int t,chw[11000],match[11000];bool findmuniu(int x) {    for(int k=last[x];k;k=a[k].next) {        int y=a[k].y;        if(chw[y]!=t) {            chw[y]=t;if(match[y]==0||findmuniu(match[y])==true) {match[y]=x;return true;}        }    }return false;}int v[110],s[110];//v在校,s回家 int main() {    int T;scanf("%d",&T);    while(T--) {        int n;scanf("%d",&n);len=0;memset(last,0,sizeof(last));        for(int i=1;i<=n;i++)scanf("%d",&v[i]);         for(int i=1;i<=n;i++)scanf("%d",&s[i]);        for(int i=1;i<=n;i++)if(v[i]==1&&s[i]==0)ins(i,i);        int cnt=0;for(int i=1;i<=n;i++)if(v[i]==0||(v[i]==1&&s[i]==0))cnt++;        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) {            int x;scanf("%d",&x);            if(x==1&&(v[i]==0||(v[i]==1&&s[i]==0))&&v[j]==1)ins(i,j);        }        bool bk=true;memset(match,0,sizeof(match));memset(chw,0,sizeof(chw));t=0;int ans=0;        for(int i=1;i<=n;i++) {            t++;if(findmuniu(i)==true)ans++;        }        if(ans==cnt)printf("^_^\n");        else printf("T_T\n");    }    return 0;}