$loj526 [LibreOJ eta Round #4]$ 子集 图论

Posted lqsukida

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$loj526 [LibreOJ eta Round #4]$ 子集 图论相关的知识,希望对你有一定的参考价值。

正解:图论

解题报告:

传送门$QwQ$

发现最大团不好求,于是考虑求最大独立集.也就把所有$gcd(i,j)cdot gcd(i+1,j+1)=1$的点之间连边,然后求最大独立集.

发现依然不可做,不妨猜结论:这张图一定是张二分图.

其实猜到了证明还是挺$easy$的$QwQ$

发现连边的点之间的奇偶性一定不同,因为若相同,$gcd$必定为2的倍数

所以这是张二分图

于是就跑个匈牙利求最大匹配数,答案就$n-$最大匹配数鸭,$over$

 

技术图片
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define int long long
#define ri register int
#define rc register char
#define rb register bool
#define lowbit(x) (x&(-x))
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)

const int N=400+10,inf=1e9;
int n,match[N];
bool vis[N];
vector<int>to[N],V[2];

il int read()
{
    rc ch=gc;ri x=0;rb y=1;
    while(ch!=- && (ch>9 || ch<0))ch=gc;
    if(ch==-)ch=gc,y=0;
    while(ch>=0 && ch<=9)x=(x<<1)+(x<<3)+(ch^0),ch=gc;
    return y?x:-x;
}
int gcd(ri x,ri y){return y?gcd(y,x%y):x;}
int dfs(ri x)
{
    vis[x]=1;
    for(auto t:to[x]){if(~match[t])if(vis[match[t]] || !dfs(match[t]))continue;match[t]=x;return 1;}
    return 0;
}

signed main()
{
    n=read();rp(i,1,n){ri x=read();V[x&1].push_back(x);}ri sz0=V[0].size(),sz1=V[1].size();
    rp(i,0,sz0-1)rp(j,0,sz1-1)if(gcd(V[0][i],V[1][j])*gcd(V[0][i]+1,V[1][j]+1)==1)to[i].push_back(j);
    memset(match,-1,sizeof(match));rp(i,0,sz0-1){memset(vis,0,sizeof(vis));n-=dfs(i);}printf("%lld
",n);  
    return 0;
}
View Code

 

以上是关于$loj526 [LibreOJ eta Round #4]$ 子集 图论的主要内容,如果未能解决你的问题,请参考以下文章

$loj530 [LibreOJ eta Round #5]$ 最小倍数 数论

「LibreOJ β Round #4」子集

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

loj536「LibreOJ Round #6」花札(二分图博弈)

[LOJ#525]「LibreOJ β Round #4」多项式

LOJ 「LibreOJ β Round #4」子集