Codeforces 1228D. Complete Tripartite

Posted lltyyc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n"); return 0; 
    if(cnt[1]*cnt[2]+cnt[2]*cnt[3]+cnt[1]*cnt[3]!=m)  printf("-1\n"); return 0; 
    for(int i=1;i<=n;i++)
    
        if(find(i)!=find(1))  printf("-1\n"); return 0; 
        int tot=0,res=0; if(!bel[i])  printf("-1\n"); return 0; 
        for(int j=fir[i];j;j=from[j])
        
            int &v=to[j]; if(bel[v]==bel[i])  printf("-1\n"); return 0; 
            tot++;
        
        for(int j=1;j<=3;j++) if(bel[i]!=j) res+=cnt[j];
        if(tot!=res)  printf("-1\n"); return 0; 
    
    for(int i=1;i<=n;i++) printf("%d ",bel[i]);
    puts(""); return 0;

 

以上是关于Codeforces 1228D. Complete Tripartite的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1228

CodeForces - 1228D (暴力+思维+乱搞)

codeforces/contest/1228

CodeForces - 1228C(质因数分解+贡献法)

codeforces 1228D - Complete Tripartite

[Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理)