hdu3335

/*
分析:
    二分匹配。
    太2了,一看到有矛盾关系瞬间就想到二分匹配了,可是太久
没做过二分匹配的题了,竟然没有想出来怎么建图?!我以前做恁
多二分匹配都白做了么囧~、都还给 OJ 了么T^T。。。
    这个题中,数字之间的关键关系是倍数么,所以用最大的(或
最小的)数,按照a是b的整数倍(或a是b的因子)的关系跑下去,最
少需要跑ans条这样的路,ans既为答案。
    这个解释应该够形象了,就是跑路么,最少的路把所有的点都
经过就行了,所以就是最少路径覆盖了。不难,不过还是贴出来,
告诉自己自己有多2&&多白痴,警示一下囧~。。。再说也有一段没
有发blog了,发一个,证明在ACM这条道儿上、lz还顽强的活着= =III。


                                                       2013-05-19
*/





#include"iostream"
#include"cstdio"
#include"cstring"
#include"algorithm"
using namespace std;
const int N=1011;

int n,match[N],vis[N];
struct Edge{
	int v,next;
}edge[N*N];
int tot,head[N];
void add(int a,int b){
	edge[tot].v=b;edge[tot].next=head[a];head[a]=tot++;
}

void build_map()
{
	int i,l,cnt;
	__int64 a[N],b[N];
	tot=0;
	memset(head,-1,sizeof(head));
	for(i=0;i<n;i++)	scanf("%I64d",&a[i]);
	sort(a,a+n);
	b[0]=a[0];
	cnt=1;
	for(i=1;i<n;i++)
	{
		if(a[i]==a[i-1])	continue;
		b[cnt++]=a[i];
	}
	n=cnt;
	for(i=0;i<n;i++)
	for(l=0;l<n;l++)
	{
		if(i==l)	continue;
		if(b[i]%b[l]==0)	add(i,l);
	}
}
int dfs(int k)
{
	int j,v;
	for(j=head[k];j!=-1;j=edge[j].next)
	{
		v=edge[j].v;
		if(vis[v])	continue;
		vis[v]=1;
		if(match[v]==-1 || dfs(match[v]))
		{
			match[v]=k;
			return 1;
		}
	}
	return 0;
}
int main()
{
	int T;
	int i;
	cin>>T;
	while(T--)
	{
		cin>>n;
		build_map();

		int ans=0;
		memset(match,-1,sizeof(match));
		for(i=0;i<n;i++)
		{
			memset(vis,0,sizeof(vis));
			ans+=dfs(i);
		}
		cout<<n-ans<<endl;
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值