Codeforces Round #589 (Div. 2) D. Complete Tripartite(模拟)
题意:给你n个点 和 m条边 问是否可以分成三个集合 使得任意两个集合之间的任意两个点都有边
思路:对于其中一个集合v1 我们考虑其中的点1 假设点u和1无边 那么我们可以得到 u一定和点1在一个集合 否则将输出-1 所以我们可以暴力把所有的点先尽可能的分类 最后判断是否可行
#include <bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; const double eps = 1e-6; const int N = 3e5+7; typedef long long ll; const ll mod = 1e9+7; using namespace std; int u[N],v[N]; int col[N]; map<int,int> mm[N]; set<int> s[4]; int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n,m; cin>>n>>m; for(int i=1;i<=m;i++){ cin>>u[i]>>v[i]; mm[u[i]][v[i]]=1; mm[v[i]][u[i]]=1; } int tot=0; for(int i=1;i<=n;i++){ if(!col[i]){ tot++; col[i]=tot; if(tot>3){ cout<<"-1"<<endl; return 0; } s[tot].insert(i); for(int j=i+1;j<=n;j++){ if(mm[i].count(j)) continue; if(col[j]) continue; col[j]=tot; s[tot].insert(j); } } } if(tot!=3){ cout<<"-1"<<endl; return 0; } for(int i=1;i<=m;i++){ if(col[u[i]]==col[v[i]]){ cout<<"-1"<<endl; return 0; } } ll a,b,c; a=s[1].size(); b=s[2].size(); c=s[3].size(); if(a*b+b*c+a*c!=m){ cout<<"-1"<<endl; return 0; } for(int i=1;i<=n;i++) cout<<col[i]<<" "; cout<<endl; return 0; }