uva 11159 Factors and Multiples

来源:互联网 发布:手机视频直播软件 编辑:程序博客网 时间:2024/06/06 09:11

You will be given two sets of integers. Let�s call them set A and set B. Set A contains n elements and set B contains m elements. You have to remove k1 elements from set A and k2 elements from set B so that of the remaining values no integer in set B is a multiple of any integer in setAk1 should be in the range [0,n] and k2 in the range [0,m].

You have to find the value of (k1+k2) such that (k1+k2) is as low as possible.

 

P is a multiple of Q if there is some integer K such that P = K * Q.

 

 

Suppose set A is {2,3,4,5} and set B is {6,7,8,9}. By removing 2 and 3 from A and 8 from B, we get the sets {4,5} and{6,7,9}. Here none of the integers 67 or 9 is a multiple of 4 or 5.

 

So for this case the answer is 3 (2 from set A and 1 from set B).

 

Input

 

The first line of input is an integer T(T<50) that determine the number of test cases. Each case consists of two lines. The first line starts with nfollowed by n integers. The second line starts with m followed by m integers. Both n and m will be in the range [1,100]. All the elements of the two sets will fit in 32 bit signed integer.

 

Output

 

For each case, output the case number followed by the answer.

 

Sample Input

Output for Sample Input

2
4 2 3 4 5
4 6 7 8 9
3 100 200 300
1 150
Case 1: 3
Case 2: 0

 

Problem Setter: Sohel Hafiz
Special Thanks: Jane Alam Jan



题目大意:

A 和 B 两个集合,从A里面删除一些数 K1 个,从 B里面删除一些数 K2 个,使得 B 中的任何一个元素 都不是 A中 的任意一个数的倍数。

解题思路:

    二部图最大匹配,只要将最大匹配中的全部左边或右边点删掉即可。


解题代码:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. #include <cstring>  
  3. #include <cstdio>  
  4. #include <cmath>  
  5. #include <set>  
  6. #include <algorithm>  
  7. using namespace std;  
  8.   
  9. const int maxn=110;  
  10. int path[maxn][maxn],visited[maxn],link[maxn];  
  11. int n,m,a[maxn],b[maxn];  
  12.   
  13. int can(int x){  
  14.     for(int i=0;i<m;i++){  
  15.         if(visited[i]==-1 && path[x][i]>0){  
  16.             visited[i]=1;  
  17.             if( link[i]==-1 || can(link[i]) ){  
  18.                 link[i]=x;  
  19.                 return 1;  
  20.             }  
  21.         }  
  22.     }  
  23.     return 0;  
  24. }  
  25.   
  26. void solve(int casen){  
  27.     int ans=0;  
  28.     for(int i=0;i<n;i++)  
  29.     for(int j=0;j<m;j++){  
  30.         if(a[i]==0){  
  31.             if(b[j]!=0) continue;  
  32.             else path[i][j]=1;  
  33.         }  
  34.         else if(b[j]%a[i]==0){  
  35.             path[i][j]=1;  
  36.         }  
  37.     }  
  38.     for(int i=0;i<n;i++){  
  39.         memset(visited,-1,sizeof(visited));  
  40.         if(can(i)) ans++;  
  41.     }  
  42.     printf("Case %d: %d\n",casen,ans);  
  43. }  
  44.   
  45. int main(){  
  46.     //freopen("in.txt","r",stdin);  
  47.     int t;  
  48.     scanf("%d",&t);  
  49.     for(int k=1;k<=t;k++){  
  50.         memset(path,0,sizeof(path));  
  51.         memset(link,-1,sizeof(link));  
  52.         scanf("%d",&n);  
  53.         for(int i=0;i<n;i++) scanf("%d",&a[i]);  
  54.         scanf("%d",&m);  
  55.         for(int i=0;i<m;i++) scanf("%d",&b[i]);  
  56.         solve(k);  
  57.     }  
  58.     return 0;  
  59. }  

0 0