bzoj1433[ZJOI2009]假期的宿舍(匈牙利)
Posted 安
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 101 using 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]假期的宿舍(匈牙利)的主要内容,如果未能解决你的问题,请参考以下文章