背景
听完了美妙的葱歌版<两个人的焰火>,F慢慢从石化中恢复了回来(= =!你以为是溪风和水碧啊).复原后的F悲哀地发现已经早晨了,他要去上学了.......
......放学后
F(回到家):= =||||||无数黑线
葱歌:What happened,怎么这么囧啊?
F:我们学校......搞唱歌比赛...= =一个MM(算不算呢?其实MM是无所谓有,无所谓无的......)唱了一首很多年前的老歌...实在太老了...老得我囧.现在脑子里全是这歌.
葱歌:是不是Nobody啊?我也会唱哦~~
F(黑线++):不要啊~
描述
众所周知的(什么?你不知道?去百度一下),Nobody的团舞里有一个经典动作(那是相当的经典,经典了好几年),而这个动作是对称做两遍的.葱歌很喜欢这个动作(Mikuer们不要BS我...),她很想多做这个动作.
但是邪恶的F,为了少看这无语的动作,给了葱歌两排非负整数.一排A数,一排B数.A数有n个,B数有m个.如果一个A数和一个B数的二进制表示法中,每一位都不一样的话(不足的数高位补0),则A和B能够组成一个"对称音".每个数只能属于一个"对称音".葱歌想要最多的对称音,让她可以尽量多跳那个动作.
格式
输入格式
输入共3行.
第1行两个正整数n,m,表示A数n个,B数m个.
第2行n个非负整数,表示n个A数.
第3行m个非负整数,表示m个B数.
输出格式
一行一个正整数,表示最多能得到的"对称音"个数.如果一个对称音都得不到,输出"I want nobody nobody but you".
限制
1s
提示
数据范围
对于10%的数据,1<=n<=10,1<=m<=10.
对于100%的数据,1<=n<=200,1<=m<=200.
二分匹配,将A和B所有连接的情况都算出来,然后进行匈牙利算法,找匹配边。O(n³)不会超时。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 const int maxn=205; 6 int vis[maxn],match[maxn]; 7 int map[maxn][maxn]; 8 int a[maxn],b[maxn]; 9 int n,m;int count; 10 inline bool dfs(int x) 11 { 12 for(int i=1;i<=m;i++) 13 { 14 if(vis[i]==false&&map[x][i]) 15 { 16 vis[i]=true; 17 if(match[i]==-1||dfs(match[i])) 18 { 19 match[i]=x; 20 return true; 21 } 22 } 23 } 24 return false; 25 } 26 inline void hungary() 27 { 28 count=0; 29 memset(match,-1,sizeof(match)); 30 for(int i=1;i<=n;i++) 31 { 32 memset(vis,false,sizeof(vis)); 33 if(dfs(i))count++; 34 } 35 return ; 36 } 37 inline bool pd(int x,int y) 38 { 39 int p1[2000],p2[2000]; 40 int temp1=0,temp2=0; 41 memset(p1,0,sizeof(p1)); 42 memset(p2,0,sizeof(p2)); 43 while(x!=0) 44 { 45 p1[++temp1]=(x&1); 46 x>>=1; 47 } 48 while(y!=0) 49 { 50 p2[++temp2]=(y&1); 51 y>>=1; 52 } 53 if(temp1<temp2) 54 { 55 for(int i=1;i<=temp1;i++) 56 if(p1[i]==p2[i])return false; 57 for(int i=temp1+1;i<=temp2;i++) 58 if(p2[i]==0)return false; 59 return true; 60 } 61 else 62 { 63 for(int i=1;i<=temp2;i++) 64 if(p1[i]==p2[i])return false; 65 for(int i=temp2+1;i<=temp1;i++) 66 if(p1[i]==0)return false; 67 return true; 68 } 69 } 70 inline void gg() 71 { 72 scanf("%d%d",&n,&m); 73 for(int i=1;i<=n;i++) 74 scanf("%d",&a[i]); 75 for(int i=1;i<=m;i++) 76 scanf("%d",&b[i]); 77 for(int i=1;i<=n;i++) 78 for(int j=1;j<=m;j++) 79 if(pd(a[i],b[j]))map[i][j]=true; 80 return ; 81 } 82 inline void print() 83 { 84 if(count==0) 85 printf("I want nobody nobody but you"); 86 else printf("%d\n",count); 87 return ; 88 } 89 int main() 90 { 91 gg(); 92 hungary(); 93 print(); 94 return 0; 95 }