• 2019牛客暑期多校训练营(第五场) maximum clique 1


    题意:给出n个不相同的数,问选出尽量多的数且任两个数字二进制下不同位数大于等于2。

    解法:能想到大于等于2反向思考的话,不难发现这是一个二分图,那么根据原图的最大团等于补图的最大独立点集,此问题就变成 任两个二进制位数相差等于1之间连边(这就是补图),然后求这个图的最大独立点集,仔细观察发现补图是个二分图。那么就可以得到最大独立点集=n-最大匹配。

    那么怎么构造一个可行方案呢?参考《算法竞赛进阶指南》的办法,1求出最大匹配  2从左边非匹配点出发跑增广路同时把路上的点标记 3最后左边非匹配点和右边匹配点组成最小点覆盖。    那么最大独立点集就是除了最小点覆盖的点啦。

    以前没写过构造最大独立点集,这题写了记录下来以免以后忘了。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e3+10;
    typedef long long LL;
    int n,col[N],match[N],a[N];
    map<LL,int> mp;
    vector<int> G[N];
    
    void dfs1(int x,int c) {
        col[x]=c;
        for (int i=0;i<G[x].size();i++) {
            int y=G[x][i];
            if (!col[y]) dfs1(y,3-col[x]);
        }
    }
    
    bool vis[N],Ans[N];
    bool dfs(int x) {
        vis[x]=1;
        for (int i=0;i<G[x].size();i++) {
            int y=G[x][i];
            if (!vis[y]) {
                vis[y]=1;
                if (!match[y] || dfs(match[y])) {
                    match[y]=x; match[x]=y;  
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        for (int i=0;i<=33;i++) mp[1LL<<i]=1;
        for (int i=1;i<=n;i++)
            for (int j=i+1;j<=n;j++)
                if (mp.count(a[i]^a[j])) G[i].push_back(j),G[j].push_back(i);
        for (int i=1;i<=n;i++)
            if (!col[i]) dfs1(i,1);         
        
        int ans=0;
        for (int i=1;i<=n;i++) {
            if (col[i]==2) continue;
            memset(vis,0,sizeof(vis));
            if (dfs(i)) ans++;
        }    
        cout<<n-ans<<endl;
        
        memset(vis,0,sizeof(vis));
        for (int i=1;i<=n;i++)
            if (col[i]==1 && !match[i]) dfs(i);
        memset(Ans,0,sizeof(Ans));    
        for (int i=1;i<=n;i++)
            if (col[i]==1 && !vis[i] || col[i]==2 && vis[i]) Ans[i]=1;
        for (int i=1;i<=n;i++)
            if (!Ans[i]) printf("%d ",a[i]);            
        return 0;
    } 
  • 相关阅读:
    JS 博客园鼠标点击效果
    安卓socket聊天
    抖音C#版,自己抓第三方抖音网站
    C#网易云音乐播放器
    反编译APK
    Raspberry Config.txt 介绍
    Raspberry U盘操作
    排序(I)
    未解决问题:
    CocoaPod 问题(I)
  • 原文地址:https://www.cnblogs.com/clno1/p/11438094.html
Copyright © 2020-2023  润新知