D. Complete Tripartite - 补题
D. Complete Tripartite
思路
题目实际上是三分图的问题,即给出一个图要求得出三分图的结果,如果得不到输出-1。
首先考虑三个集合的选取:我们可以直接让第1个点(点x)为集合1,(如果此点是孤立点则无法构成三分图,输出-1即可),然后在此点的邻接点中任意选出1个点(点y)作为集合2,最后筛选这两个点的公共邻接点,若不存在则无法构成三分图,直接输出-1,找到公共点(点z)后作为集合3。
完成3个集合的选取后,遍历所有点判断它的所有邻接点是否存在x,y,z中的两个,若不满足则无法构成三分图(因为三分图每个集合的点和其他集合中的所有点都邻接,但是与自己集合中的点都不邻接),满足条件就将其染成缺失的点所在集合的颜色。
完成染色后判断总边数是否满足条件,根据三分图的定义可以得到这个三分图的边数:3个集合的元素个数两两相乘再求和就是总边数,判断是否等于给出的m
最后判断每个点相邻的顶点中是否存在与自己颜色相同的点,若存在则不满足定义输出-1。
Code
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int N=1e5+7;
const ll mod=1e9+7;
vector<int>u[N];
int color[N];
int vis[N],flag=1;
int main(){
IO;
int t=1;
//cin>>t;
while(t--){
int n,m;
cin>>n>>m;
for (int i = 0; i < m; ++i)
{
int x,y;
cin>>x>>y;
u[x].push_back(y);
u[y].push_back(x);
}
color[1]=1;
int x=1,y=0,z=0;
for (auto i:u[x])
{
y=i;
break;
}
if(!y){
cout<<-1<<endl;
continue;
}
for (auto i:u[x])
{
for (auto j:u[y])
{
if(i!=x&&i!=y&&i==j){
z=i;
break;
}
}if(z)break;
}
if(!z){
cout<<-1<<endl;
continue;
}
for (int i = 1; i <= n; ++i)
{
int x1=0,x2=0,x3=0;
for (auto j:u[i])
{
if(j==x)x1++;
if(j==y)x2++;
if(j==z)x3++;
}
if(x1+x2+x3!=2){
cout<<-1<<endl;
return 0;
}
if(x1&&x2&&!x3)color[i]=3;
if(x1&&!x2&&x3)color[i]=2;
if(!x1&&x2&&x3)color[i]=1;
}int a[5]={0};
for (int i = 1; i <= n; ++i)
{
a[color[i]]++;
}
if(a[1]*a[2]+a[1]*a[3]+a[2]*a[3]!=m){
cout<<-1<<endl;
continue;
}
for (int i = 1; i <= n; ++i)
{
for(auto j:u[i]){
if(color[i]==color[j]){
cout<<-1<<endl;
return 0;
}
}
}
for (int i = 1; i <= n; ++i)
{
cout<<color[i]<<" ";
}cout<<endl;
}
return 0;
}
判断条件有点多,搞得有点晕。
今天也要努力啊!!!
Code will change the world !

浙公网安备 33010602011771号