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。
我的做法:比较裸的最大匹配。。但是容易错的地方是:i==j时连边但要注意i是否为该校学生!T_T... WA了很多次。。还有多数据时注意初始值。。
#include<queue> #include<vector> #include<cstdio> #include<bitset> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> const int inf = 2147483647; using namespace std; const int N = 60; #define For(i,n) for(int i=1;i<=n;++i) #define Rep(i,l,r) for(int i=l;i<=r;++i) struct EDGE{ int t,next; }E[N*N]; bitset<N> used; int T,n,yes[N],state[N];//每个学生,描述两个属性:是否该校,是否回家。 int Link[N],con,cnt,head[N]; void makelist(int s,int t){ E[cnt].t = t; E[cnt].next = head[s]; head[s] = cnt++; } void init(){ memset(head,-1,sizeof(head)); scanf("%d",&n); For(i,n) scanf("%d",&yes[i]); For(i,n){ scanf("%d",&state[i]); if(!yes[i]) state[i] = inf; } For(i,n) For(j,n){ scanf("%d",&con); if(con&&yes[j]) makelist(i,j); if(i==j&&yes[i]) makelist(i,j); } } bool find(int u){ for(int p = head[u];p!=-1;p=E[p].next){ int v = E[p].t; if(!used[v]){ used[v] = 1; if(!Link[v]||find(Link[v])){ Link[v] = u; return true; } } } return false; } void solve(){ For(i,n) if(state[i]==inf||state[i]==0){ used.reset(); if(!find(i)){ printf("T_T "); return; } } printf("^_^ "); } int main(){ scanf("%d",&T); while(T){ memset(yes,0,sizeof(yes)); memset(state,0,sizeof(state)); memset(Link,0,sizeof(Link)); cnt = 0; init(); solve();T--; } return 0; }