codeforces 1228D - Complete Tripartite

// 三点分图,还是挺简单的,讲下思路:先把所有的点分为3个集合,
//judge下集合不能为空,集合内的点不能有连线,最后judge下边数
#include<bits./stdc++.h>
using namespace std;
typedef long long i64;
const int maxn = 1e5 + 32;
int n,m,u,v,col[maxn];
set<int> Grape[maxn];
i64 arr[8];
int main()
{
    ios::sync_with_stdio(false);    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=0;i!=m;++i)
    {
        cin>>u>>v;
        Grape[u].insert(v);
        Grape[v].insert(u);
    }
    col[1] = 1;
    for(int i=2;i<=n;++i)
        if(!Grape[1].count(i))
            col[i] = 1;
    for(int i=2;i<=n;++i)
        if(!col[i])//如果节点i未被访问
        {
            col[i] = 2;//寻找一个集合2
            for(int j=1;j<=n;++j)
            {
                if(!Grape[i].count(j))
                {
                    if(col[j]==1)
                    {
                        cout<<-1<<'\n';
                        return 0;
                    }
                    col[j] = 2;
                }
            }
            break;
        }//2号标记
    for(int i=1;i<=n;++i)
        if(!col[i])
            col[i] = 3;
    for(int i=1;i<=n;++i)
    {
        for(auto v :Grape[i])
            if(col[v] == col[i])
            {
                cout<<-1<<'\n';
                return 0;
            }
    }//集合内的边去重
    for(int i=1;i<=n;++i)
        ++arr[col[i]];
    if(!arr[1]||!arr[2]||!arr[3])
        cout<<"-1"<<'\n';
    else if((arr[1]*arr[2]+arr[1]*arr[3]+arr[2]*arr[3])!=m)
        cout<<-1<<"\n";
    else{
        for(int i=1;i<=n;++i)
            cout<<col[i]<<" ";
        cout<<'\n';
    }
}

  

猜你喜欢

转载自www.cnblogs.com/newstartCY/p/11622734.html