码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-09-30 21:53:41      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:mem   mil   div   tin   nbsp   fine   auto   img   ack   

正解:图论

解题报告:

传送门$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",n);  
    return 0;
}
View Code

 

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

标签:mem   mil   div   tin   nbsp   fine   auto   img   ack   

原文地址:https://www.cnblogs.com/lqsukida/p/11614089.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!