Codeforces Round #589 (Div. 2) D. Complete Tripartite

题目地址:https://codeforces.com/contest/1228/problem/D

题意:给你n个点,m条边,能否构成三分图,每条边都要用上

思路:分三个集合f1、f2、f3,与f1、f2相连但与f3不相连的,与f2、f3相连但与f1不相连的,与f1、f3相连但与f2不相连的。三分图的原因,可以直接取点1作为集合一的一个点a1,再取与1相连的第一个点作为第二个集合的点a2,接着找到与点一点二都相连的点a3。然后就是遍历所有的点,分类到三个集合中去,检测所得的三分图的边是否与m相同和每个集合里的边是否有相连的即可。

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 using namespace std;
 7 typedef long long ll;
 8 const int MAXN=1e5+5;
 9 int n,m;
10 vector<int>a[MAXN];
11 void sol(){
12     if(a[1].size()==0){
13         cout<<"-1";
14         return ;
15     }
16     int f1=1,f2=0,f3=0;
17     int color[MAXN];
18     memset(color,0,sizeof(color));
19     f2=a[f1][0];
20     color[1]=1;
21     color[a[f1][0]]=2;
22     for(int j=1;j<=n;j++){     //找到f2和f3
23         bool a1=false,a2=false;
24         for(int i=0;i<a[j].size();i++){
25             if(a[j][i]==f1) a1=true;
26             if(a[j][i]==f2) a2=true;
27         }
28         if(a1&&a2){
29             f3=j;
30             break;
31         }
32     }
33     if(!f3){      //若没有f3则直接输出-1
34         cout<<"-1";
35         return ;
36     }
37     color[f3]=3;
38     for(int i=1;i<=n;i++){   //分到各个集合里
39         int a1=0,a2=0,a3=0;
40         for(int j=0;j<a[i].size();j++){   //检测i点与f1,f2,f3那些点相连
41             if(a[i][j]==f1) a1=1;
42             if(a[i][j]==f2) a2=1;
43             if(a[i][j]==f3) a3=1;
44         }
45         if(a1+a2+a3!=2){    //若不是与其中两个点相连则直接输出-1
46             cout<<"-1";
47             return ;
48         }
49         if(a1&&a2&&!a3) color[i]=3;
50         if(a1&&!a2&&a3) color[i]=2;
51         if(!a1&&a2&&a3) color[i]=1;
52     }
53     int cnt[4]={0};
54     for(int i=1;i<=n;i++) cnt[color[i]]++;      
55     if(cnt[1]*cnt[2]+cnt[2]*cnt[3]+cnt[3]*cnt[1]!=m){       //计算边的数量是否为m
56         cout<<"-1";
57         return ;
58     }
59     for(int i=1;i<=n;i++){       //回路判断,检查每个集合里是否有相连的
60         for(int j=0;j<a[i].size();j++){
61             if(color[i]==color[a[i][j]]){
62                 cout<<"-1";
63                 return ;
64             }
65         }
66     }
67     for(int i=1;i<=n;i++)
68         cout<<color[i]<<" ";
69 }
70 int main(){
71     cin>>n>>m;
72     int x,y;
73     for(int i=0;i<m;i++){
74         cin>>x>>y;
75         a[x].push_back(y);
76         a[y].push_back(x);
77     }
78     sol();
79     return 0;
80 }

其中检测边的步骤,我试过去检测每个点是否都用上了,但WA了,有点懵。

posted @ 2019-10-15 19:50  xunzf  阅读(120)  评论(0编辑  收藏  举报