题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=12756
Social Holidaying
3000ms
131072KB
This problem will be judged on UVALive. Original ID: 5874
64-bit integer IO format: %lld Java class name: Main
64-bit integer IO format: %lld Java class name: Main
Font Size:
Source
题目大意:先输入一个P表示有几组测试数据,再输入一个n,m分别表示A、B集合中分别有多少元素。在A集合中找到多少对数相加=B集合中的元素。A集合中的数不可以重复,但是B集合中的数字可以重复出现。
解题思路:二分匹配。先将A集合中的和的所有可能情况列出来,然后在B集合中搜索即可。
详见代码。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 int ss[9999999],Map[410][410]; 8 int ok[410],vis[410]; 9 int a[410],b[410]; 10 int n,m; 11 12 bool Find(int x) 13 { 14 for (int i=1; i<=n; i++) 15 { 16 if (!vis[i]&&Map[x][i]==1) 17 { 18 vis[i]=1; 19 if (!ok[i]) 20 { 21 ok[i]=x; 22 return true; 23 } 24 else 25 { 26 if (Find(ok[i])) 27 { 28 ok[i]=x; 29 return true; 30 } 31 } 32 } 33 } 34 return false; 35 } 36 37 int main() 38 { 39 int t; 40 scanf("%d",&t); 41 while (t--) 42 { 43 scanf("%d%d",&n,&m); 44 int ans=0; 45 memset(vis,0,sizeof(vis)); 46 memset(Map,0,sizeof(Map)); 47 memset(ok,0,sizeof(ok)); 48 memset(ss,0,sizeof(ss)); 49 for (int i=1; i<=n; i++) 50 { 51 scanf("%d",&a[i]); 52 } 53 for (int i=1; i<=m; i++) 54 { 55 scanf("%d",&b[i]); 56 ss[b[i]]=1; 57 } 58 for (int i=1; i<=n; i++) 59 { 60 for (int j=i+1; j<=n; j++) 61 { 62 if (ss[a[i]+a[j]]==1) 63 Map[i][j]=Map[j][i]=1; 64 } 65 } 66 for (int i=1; i<=n; i++) 67 { 68 memset(vis,0,sizeof(vis)); 69 if (Find(i)) 70 ans++; 71 } 72 printf ("%d ",ans/2); 73 } 74 return 0; 75 }