$loj526 [LibreOJ eta Round #4]$ 子集 图论
Posted lqsukida
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$loj526 [LibreOJ eta Round #4]$ 子集 图论相关的知识,希望对你有一定的参考价值。
正解:图论
解题报告:
发现最大团不好求,于是考虑求最大独立集.也就把所有$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; }
以上是关于$loj526 [LibreOJ eta Round #4]$ 子集 图论的主要内容,如果未能解决你的问题,请参考以下文章
$loj530 [LibreOJ eta Round #5]$ 最小倍数 数论
LibreOJ #526. 「LibreOJ β Round #4」子集
loj536「LibreOJ Round #6」花札(二分图博弈)