zoukankan      html  css  js  c++  java
  • 【HNOI】trust 弦图最大独立集

      【题目描述】有n个人,每个人之间都有是否信任的关系,要求找出k个人,使得k个人之间彼此信任,且k最大,保证不信任的关系由多个三元环组成,且三元环之间只可能有公共点,没有公共边,且不存在任意一个节点不属于任意一个三元环。

      【数据范围】

        n<=2000。

      首先我们可以建立信任关系的反图,这样的出的图为弦图,那么我们只需要求出各个块的完美消除序列,然后再通过完美消除序列求出该图的最大独立集就可以了。

      反思:开始脑残求的是最小染色,然后算的相同颜色的数量取max。

    //By BLADEVIL
    #include <cstdio>
    #include <cstring>
    #define maxn 2010
    
    using namespace std;
    
    int n,l;
    int other[maxn*maxn],pre[maxn*maxn],last[maxn],flag[maxn],size[maxn],ans[maxn],que[maxn];
    
    void connect(int x,int y) {
        pre[++l]=last[x];
        last[x]=l;
        other[l]=y;
    }
    
    int main() {
        freopen("trust.in","r",stdin); freopen("trust.out","w",stdout);
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++) {
                int x; scanf("%d",&x);
                if (!x) connect(i,j);
            }
        for (int i=n;i;i--) {
            int cur=0;
            for (int j=1;j<=n;j++) if ((size[j]>=size[cur])&&(!flag[j])) cur=j;
            que[i]=cur; flag[cur]=1;
            for (int p=last[cur];p;p=pre[p]) size[other[p]]++;
        }
        //for (int i=1;i<=n;i++) printf("%d ",que[i]); printf("
    ");
        memset(flag,0,sizeof flag);
        for (int i=1;i<=n;i++) {
            int cur=que[i];
            if (flag[cur]) continue;
            ans[++ans[0]]=cur;
            for (int p=last[cur];p;p=pre[p]) flag[other[p]]=1;
        }
        printf("%d
    ",ans[0]);
        for (int i=1;i<=ans[0];i++) printf("%d ",ans[i]); printf("
    ");
        fclose(stdin); fclose(stdout);
        return 0;
    }
  • 相关阅读:
    [BZOJ 2653]middle
    svn提交错误
    查看当前功能地址
    后台纯代码--短信验证
    图片验证码~~~之后台生成随机数
    小程序之~~登录后台代码
    小程序登录过程简介
    小程序之~微信登录后台代码
    小程序之~~基于微信登录,后台代码
    小程序之~~短信验证
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3638691.html
Copyright © 2011-2022 走看看