题意::从中选出最多的数能够使得其两两之间不能整除
既然是找两两之间不能整除的集合里面的个数,那就是用所有的点减去能够匹配到的整除的匹配数就行,这就是最大独立集
都说这题需要去重但是可以不用去,但需要全排一下,从小到大排列,然后具体看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ms(a,b) memset(a,b,sizeof a)
typedef long long ll;
const int N=30010;
const int INF=0x3f3f3f3f;
int n;
ll a[1010];
int e[1010][1010];
bool vis[1010];
int ans;
int book[1010];
bool found(int v)
{
rep(i,1,n)
{
if(!vis[i]&&e[v][i])
{
vis[i]=1;
if(book[i]==-1||found(book[i]))
{
book[i]=v;return 1;
}
}
}
return false;
}
int pitch()
{
ans=0;
ms(book,-1);
rep(i,1,n)
{
ms(vis,0);
if(found(i)) ans++;
}
return ans;
}
int main() {
int t;
scanf("%d",&t);
while(t--){
ms(a,0);ms(e,0);ans=0;
scanf("%d",&n);
rep(i,1,n)
scanf("%I64d",&a[i]);
sort(a+1,a+1+n);//如果不加sort,那样例3 2 1就是3,明显是不对的
rep(i,1,n)//需要建立一个有向图来实现二分图的匹配,排完之后就能保证后面的元素都是比前面的大
rep(j,i+1,n)//这样就是看是否两者能够整除
{
if((a[j]%a[i]==0))
e[j][i]=1//e[j][i]=1;如果建立无向图的话就有可能出现问题,但这道题是不会的
}
printf("%d\n",n-pitch());
}
return 0;
}
下面是需要去重的
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ms(a,b) memset(a,b,sizeof a)
typedef long long ll;
const int N=30010;
const int INF=0x3f3f3f3f;
int n;
ll a[1010];
int e[1010][1010];
bool vis[1010];
int ans;
int book[1010];
ll b[1010];
bool found(int v)
{
rep(i,1,n)
{
if(!vis[i]&&e[v][i])
{
vis[i]=1;
if(book[i]==-1||found(book[i]))
{
book[i]=v;return 1;
}
}
}
return false;
}
int pitch()
{
ans=0;
ms(book,-1);
rep(i,1,n)
{
ms(vis,0);
if(found(i)) ans++;
}
return ans;
}
int main() {
int t;
scanf("%d",&t);
while(t--){
ms(a,0);ms(e,0);ans=0;ms(b,0);
scanf("%d",&n);
rep(i,1,n)
scanf("%I64d",&a[i]);
sort(a+1,a+1+n);
int cont=0;
rep(i,1,n)
if(a[i]==a[i-1]) continue;
else b[++cont]=a[i];
n=cont;
rep(i,1,cont)
rep(j,1,cont)
{
if(i==j) continue;
if(b[i]%b[j]==0)
e[j][i]=1;//e[j][i]=1;
}
printf("%d\n",n-pitch());
}
return 0;
}