• Codeforces 1228D. Complete Tripartite


    传送门

    不妨设 $1$ 号点在集合 $1$ 里

    那么对于其他点,有且只有所有和 $1$ 没有边的点都在集合 $1$ 里

    考虑不在集合 $1$ 的任意一个点 $x$ ,不妨设它在集合 $2$ 里

    那么所有不在集合 $1$ 的,和 $x$ 没有边的点都在集合 $2$ 里,剩下的点都一定在集合 $3$ 里

    所以集合划分完毕,然后就是判断合法性了,特判当然是越多越好啦!

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=6e5+7;
    int n,m,bel[N],cnt[4];
    int fir[N],from[N<<1],to[N<<1],cntt;
    inline void add(int a,int b) { from[++cntt]=fir[a]; fir[a]=cntt; to[cntt]=b; }
    int fa[N];
    inline int find(int x) { return x!=fa[x] ? fa[x]=find(fa[x]) : x; }
    int main()
    {
        n=read(),m=read(); int a,b;
        for(int i=1;i<=n;i++) fa[i]=i;
        for(int i=1;i<=m;i++)
        {
            a=read(),b=read();
            add(a,b); add(b,a); fa[find(a)]=find(b);
        }
        bel[1]=1; cnt[1]++;
        for(int i=2;i<=n;i++)
        {
            bool GG=0;
            for(int j=fir[i];j;j=from[j])
            {
                int &v=to[j]; if(v==1) GG=1;
            }
            if(!GG&&!bel[i]) bel[i]=1,cnt[1]++;
        }
        int x=0;
        for(int i=fir[1];i;i=from[i])
        {
            x=to[i]; break;
        }
        bel[x]=2; cnt[2]++;
        for(int i=1;i<=n;i++)
        {
            bool GG=0; if(bel[i]) continue;
            for(int j=fir[i];j;j=from[j])
            {
                int &v=to[j]; if(v==x) GG=1;
            }
            if(!GG) bel[i]=2,cnt[2]++;
            else bel[i]=3,cnt[3]++;
        }
        for(int i=1;i<=3;i++) if(!cnt[i]) { printf("-1
    "); return 0; }
        if(cnt[1]*cnt[2]+cnt[2]*cnt[3]+cnt[1]*cnt[3]!=m) { printf("-1
    "); return 0; }
        for(int i=1;i<=n;i++)
        {
            if(find(i)!=find(1)) { printf("-1
    "); return 0; }
            int tot=0,res=0; if(!bel[i]) { printf("-1
    "); return 0; }
            for(int j=fir[i];j;j=from[j])
            {
                int &v=to[j]; if(bel[v]==bel[i]) { printf("-1
    "); return 0; }
                tot++;
            }
            for(int j=1;j<=3;j++) if(bel[i]!=j) res+=cnt[j];
            if(tot!=res) { printf("-1
    "); return 0; }
        }
        for(int i=1;i<=n;i++) printf("%d ",bel[i]);
        puts(""); return 0;
    }
  • 相关阅读:
    【iOS】去掉Tabbar顶部线条
    iOS中控制器的释放问题
    码云平台帮助文档_V1.2
    iOS键盘 样式/风格
    cocoapods的安装 升级版
    Unity异常捕获
    tomcat和jdk的安装配置
    Unity读取Excel表格
    NFS
    K8S存储相关yaml
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11612340.html
Copyright © 2020-2023  润新知