codeforces(D. Complete Tripartite)三分图

原题链接

个人感觉这道题出的挺好

给你n个点,m条边,确定出一个三分图,即把点分成三组,每组内的点之间不能直接到达,任意一点必须能直接到达非本组的所有点

首先将1号点定为1组,然后遍历1号点的所有出边,凡是与1号点相连的都为2组,剩余的为1组,在从2组中随便选一个点,遍历这个点的所有出边,凡是与这个点相连的且不为1组的都设为3组
这样先分成三组,然后判断组内的点满不满足题意,即组内的点不可相连

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

struct node
{
    
    
    int to,next;
}q[600005];
int head[300005],cnt=1;
int d[300005];
vector<int>v1,v2;
void add(int x,int y)
{
    
    
    q[cnt].to=y;
    q[cnt].next=head[x];
    head[x]=cnt++;
}
int main()
{
    
    
    memset(head,-1,sizeof(head));
    int n,m,a,b;
    scanf("%d %d",&n,&m);
    for(int i=0;i<m;i++)
    {
    
    
        scanf("%d %d",&a,&b);
        v1.push_back(a);v2.push_back(b);
        add(a,b);add(b,a);
    }
    d[1]=1;
    int val;
    for(int i=head[1];i!=-1;i=q[i].next)
    {
    
    
        int v=q[i].to;
        d[v]=2;
        val=v;
    }
    d[val]=2;
    for(int i=head[val];i!=-1;i=q[i].next)
    {
    
    
        int v=q[i].to;
        if(d[v]==2)
        {
    
    d[v]=3;}
    }
    ll a1=0,a2=0,a3=0;
    for(int i=1;i<=n;i++)
    {
    
    
        if(d[i]==0||d[i]==1)
        {
    
    d[i]=1;a1++;}
        if(d[i]==2)
        {
    
    a2++;}
        if(d[i]==3)
        {
    
    a3++;}
    }
    if(a1==0||a2==0||a3==0)
    {
    
    printf("-1\n");return 0;}
    if(a1*a2+a1*a3+a2*a3==m)
    {
    
    
        int flag=1;
        for(int i=0;i<m;i++)
        {
    
    
            if(d[v1[i]]==d[v2[i]])
            {
    
    flag=0;break;}
        }
        if(!flag)
        {
    
    printf("-1\n");}
        else
        {
    
    
            for(int i=1;i<=n;i++)
            {
    
    printf("%d ",d[i]);}
            printf("\n");
        }
    }
    else
    {
    
    printf("-1\n");}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/105591253