三分图染色
链接:https://codeforces.com/contest/1228/problem/D
三分图染色步骤:First 首先找一个点1作为集合A中的点,再找到与1相连的一个点设为2,作为集合2中的首元素,再找到与1和2相连的一个点作为集合三的元素。
Second 枚举每一个点,判断该点是否同时与原先定义的三个点其中的两个相连,如果不相连则退出,输出-1。
Third,判断当前的点构成的边,与总边数是否相等,如果不相等则输出-1
Fourth 判断自己集合中的点时候有边;
AC代码:
#include<bits/stdc++.h> using namespace std; const int N=1e5+7; vector<int >ve[N]; int arr[N]; int cnt[N]; int main(){ int n,m; cin>>n>>m; for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; ve[x].push_back(y); ve[y].push_back(x); } int first=1; arr[first]=1; if(ve[first].size()==0) { cout<<-1<<endl; return 0; } int second=ve[first][0]; arr[second]=2; int third=0; for(int i=1;i<=n;i++){ bool flag1=false ,flag2=false ; if(i==second||i==first) continue ; for(int j=0;j<ve[i].size();j++){ if(ve[i][j]==first) flag1=true; if(ve[i][j]==second) flag2=true; } if(flag1&&flag2){ third=i; arr[i]=3; break; } } if(third==0){ cout<<-1<<endl; return 0; } for(int i=1;i<=n;i++){ if(i==first||i==second||i==third) continue ; int flag1=0,flag2=0,flag3=0; for(int j=0;j<ve[i].size();j++){ if(ve[i][j]==first) flag1=1; if(ve[i][j]==second) flag2=1; if(ve[i][j]==third) flag3=1; } if(flag1+flag2+flag3!=2) { cout<<-1<<endl; return 0; } if(flag1&&flag2) arr[i]=3; if(flag1&&flag3) arr[i]=2; if(flag2&&flag3) arr[i]=1; } for(int i = 1; i <= n; i ++) cnt[arr[i]] ++;//判断每个颜色一共有个点 if(cnt[1]*cnt[2] + cnt[2]*cnt[3] + cnt[1]*cnt[3] != m) {//每两种颜色都可以产生一条边 cout << -1 << endl; return 0; } for(int i=1;i<=n;i++){ for(int j=0;j<ve[i].size();j++){ if(arr[i]==arr[ve[i][j]]) { cout<<-1<<endl; return 0; } } } for(int i=1;i<=n;i++) cout<<arr[i]<<" "; cout<<endl; return 0; }