最小路径覆盖:Divisibility

Divisibility Time Limit:1000MS    Memory Limit:32768KB    64bit IO Format:%I64d & %I64u

Description

As we know,the fzu AekdyCoin is famous of math,especially in the field of number theory.So,many people call him "the descendant of Chen Jingrun",which brings him a good reputation.
AekdyCoin also plays an important role in the ACM_DIY group,many people always ask him questions about number theory.One day,all members urged him to conduct a lesson in the group.The rookie daizhenyang is extremely weak at math,so he is delighted.
However,when AekdyCoin tells us "As we know, some numbers have interesting property. For example, any even number has the property that could be divided by 2.",daizhenyang got confused,for he don't have the concept of divisibility.He asks other people for help,first,he randomizely writes some positive integer numbers,then you have to pick some numbers from the group,the only constraint is that if you choose number a,you can't choose a number divides a or a number divided by a.(to illustrate the concept of divisibility),and you have to choose as many numbers as you can.
Poor daizhenyang does well in neither math nor programming.The responsibility comes to you!
 

Input

An integer t,indicating the number of testcases,
For every case, first a number n indicating daizhenyang has writen n numbers(n<=1000),then n numbers,all in the range of (1...2^63-1).
 

Output

The most number you can choose.
 

Sample Input

     
     
1 3 1 2 3
 

Sample Output

     
     
2 Hint: If we choose 2 and 3,one is not divisible by the other,which is the most number you can choose.
 
一开始想错了,想把不能除尽的连一块儿,然后找最长的路径
后来发现这样一来可能有问题,另一方面要找路径的长度貌似不太可行
正确做法是把能除尽的连一块儿,然后找最小覆盖路径的数量

#include <iostream>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int MAXN=1010;
int uN,vN;  //u,v数目
int g[MAXN][MAXN];//编号是0~n-1的
int linker[MAXN];//是否有父亲,如果有,父亲是谁
bool used[MAXN]; //在本次dfs中是否在路径中被指过
bool dfs(int u){
    int v;
    for(v=0;v<vN;v++)
        if(g[u][v]&&!used[v]){
            used[v]=true;
            if(linker[v]==-1||dfs(linker[v])){//v没有父亲或v的父亲有其他儿子
                linker[v]=u;
                return true;
            }
        }
    return false;
}

int hungary(){
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0;u<uN;u++){
        memset(used,0,sizeof(used));
        if(dfs(u))  res++;
    }
    return res;
}

bool cmp(long long a, long long b){
    return a > b;
}

long long num[1010];

int main(){
    int t;
    int n;
    int i, j;
    scanf("%d", &t);
    while(t --){
        scanf("%d", &n);
        for(i = 0; i < n; i ++){
            scanf("%I64d", &num[i]);
        }
        memset(g, 0, sizeof(g));
        sort(num, num + n, cmp);
//        for(i = 0; i < n; i ++)
//            printf("%I64d ", num[i]);
        uN = n;
        vN = n;
        for(i = 0; i < n ; i ++){
            for(j = i + 1; j < n; j ++){
                if(num[i] % num[j] == 0){
                    g[i][j] = 1;
                }
            }
        }
        int ans = n - hungary();
        printf("%d\n", ans);
    }
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值