CF #589 (Div. 2) D. Complete Tripartite 构造

这个 D 还是十分友好的~

你发现这 $3$ 个集合形成了一个环的关系,所以随意调换顺序是无所谓的. 

然后随便让 $1$ 个点成为第 $2$ 集合,那么不与这个点连边的一定也属于第二集合. 

然后再随便找一个与所选点有连边的点,将这个设为第 $3$ 集合中的点,然后与这个点有连边且不为第二集合的就是第一集合的. 

构造出了 $3$ 个集合后再判断一下是否不合法即可. 

几个判断方式: 

1. 一个集合中不能有连边

2. 任意一个集合中所有点出边的数量应该相同. 

3. 任何一个点集都不能为空. 

#include <bits/stdc++.h>
#define N 100004 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
vector<int>G[N];  
int vised[N],ty[N],cnt[N];       
int main() 
{
    // setIO("input"); 
    int n,m,i,j,flag=0;      
    scanf("%d%d",&n,&m); 
    for(i=1;i<=m;++i) 
    {
        int a,b; 
        scanf("%d%d",&a,&b); 
        G[a].push_back(b); 
        G[b].push_back(a); 
    }
    ty[1]=2; 
    cnt[2]=1; 
    for(i=0;i<G[1].size();++i) 
    {
        int v=G[1][i]; 
        vised[v]=1;    
    }
    // 对2染色.    
    for(i=2;i<=n;++i) if(!vised[i]) ty[i]=2, ++cnt[2];      
    // 判断 2 有没有不合法的.
    /* 
    for(i=2;i<=n;++i) 
    {
        if(ty[i]==2) 
        {
            for(j=0;j<G[i].size();++j) 
            {
                int v=G[i][j]; 
                if(ty[v]==2) flag=1;     
            }
        }
    }
    */     
    // 对 3 染色.    
    for(i=1;i<=n;++i) 
    {
        if(vised[i]) 
        {
            for(j=0;j<G[i].size();++j) 
            {
                int v=G[i][j]; 
                if(!ty[v]) 
                { 
                    ty[v]=1;      
                    ++cnt[1];      
                }
            }
            ty[i]=3;   
            ++cnt[3];    
            break; 
        }
    }   
    for(i=1;i<=n;++i) if(!ty[i]) ty[i]=3, ++cnt[3];     
    for(i=1;i<=n;++i) 
    {
        if(ty[i]==1) 
        {
            for(j=0;j<G[i].size();++j) 
            {
                int v=G[i][j]; 
                if(ty[v]==1) flag=1; 
            }
            if(G[i].size()!=cnt[2]+cnt[3]) flag=1;    
        }
        if(ty[i]==2) 
        {
            for(j=0;j<G[i].size();++j) 
            {
                int v=G[i][j]; 
                if(ty[v]==2) flag=1; 
            }
            if(G[i].size()!=cnt[1]+cnt[3]) flag=1; 
        }
        if(ty[i]==3) 
        {
            for(j=0;j<G[i].size();++j) 
            {
                int v=G[i][j]; 
                if(ty[v]==3) flag=1;     
            }
            if(G[i].size()!=cnt[1]+cnt[2]) flag=1;    
        }
    } 
    for(i=1;i<=n;++i) if(!ty[i]) flag=1; 
    if(!cnt[1]||!cnt[2]||!cnt[3]) flag=1;             
    if(flag) printf("-1\n"); 
    else
    {
        for(i=1;i<=n;++i) printf("%d ",ty[i]);     
    }
    return 0;    
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/11610976.html