loj#526. 「LibreOJ β Round #4」子集

来源:互联网 发布:前端整么添加数据 编辑:程序博客网 时间:2024/06/03 05:07

给N个点,给出建边的条件,求图中的最大团,直接跑最大团模板会超时,建个对偶图,跑二分图匹配,最大团子集中点的个数就是n-匹配数

#include<cstdio>#include<cstring>using namespace std;const int maxn = 505;int n;long long num[maxn];int match[maxn];int vis[maxn];int bmap[maxn][maxn];long long gcd(long long a, long long b){ return a == 0 ? b : gcd(b % a, a); }bool dfs(int u){    vis[u] = 1;    for(int i=1;i<=n;i++)    {        if(i==u||vis[i]||bmap[u][i]) continue;        if(match[i]==-1||!vis[match[i]]&&dfs(match[i]))        {            match[i] = u;            match[u] = i;            return true;        }    }    return false;}int max_match(){    int ans = 0;    memset(match,-1,sizeof(match));    for(int i=1;i<=n;i++)    {        if(match[i]==-1){            memset(vis,0,sizeof(vis));            if(dfs(i)) ans ++;        }    }    return ans;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%lld",&num[i]);    memset(bmap,0,sizeof(bmap));    for(int i=1;i<=n;i++)    {        for(int j=i+1;j<=n;j++)        {            if(gcd(num[i],num[j])*gcd(num[i]+1,num[j]+1)!=1)            {                bmap[i][j] = 1; bmap[j][i] = 1;            }        }    }    printf("%d\n",n-max_match());    return 0;}


原创粉丝点击