首页 > 代码库 > bzoj1433[ZJOI2009]假期的宿舍(匈牙利)
bzoj1433[ZJOI2009]假期的宿舍(匈牙利)
1433: [ZJOI2009]假期的宿舍
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2544 Solved: 1074
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。
/*看这个题,不难发现是二分图,裸的匈牙利。 也很好想到要把人和床分开建图。 但是容易吧不在校的和在校的人分开。其实不该分开,建图是没有任何影响的有一点要注意,很容易忽略把在校的人和自己的床建边,忘了就WA了!预处理稍麻烦。 */ #include<iostream>#include<cstdio>#include<cstring>#define maxn 101using namespace std;int T,n,m,k,ans,cnt1,cnt2;int bed[maxn],vis[maxn],Link[maxn],Judge[maxn],people[maxn];int a[maxn][maxn];inline int insert(){ int x=0,f=1;char c=getchar(); while(c>‘9‘||c<‘0‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f;}inline void first(){ ans = 0; memset(a,0,sizeof(a)); memset(bed,0,sizeof(bed)); memset(Judge,0,sizeof(Judge)); memset(people,0,sizeof(people)); memset(Link,0,sizeof(Link)); cnt1=cnt2=0;}bool hungarian(int x){ for(int i=1;i<=cnt1;i++) { if(a[x][bed[i]]&&!vis[bed[i]]) { vis[bed[i]]=1; if(!Link[bed[i]]||hungarian(Link[bed[i]])) { Link[bed[i]]=x; return true; } } } return false;}int main(){ T=insert(); while(T--) { first(); n=insert(); for(int i=1;i<=n;i++) Judge[i]=insert(); for(int i=1;i<=n;i++) { int tmp; tmp=insert(); if(Judge[i]) { if(tmp) bed[++cnt1]=i;//不在校的 else bed[++cnt1]=people[++cnt2]=i;//在校的 } else people[++cnt2]=i;//来探望的 } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=insert(); for(int i=1;i<=n;i++) if(Judge[i]) a[i][i]=1;//自己的床 for(int i=1;i<=cnt2;i++) { memset(vis,0,sizeof(vis)); if(hungarian(people[i]))//if后面又打成了分号,罚自己中午多吃一个馒头2333 ans++; } if(cnt2>cnt1) ans=-1; if (ans == cnt2) printf("^_^\n"); else printf("T_T\n"); } return 0;}
bzoj1433[ZJOI2009]假期的宿舍(匈牙利)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。