Codeforces Round #589 (Div. 2) D
比赛时以为点的度数搞搞就行,然后wa了。
题目:
一张图 n 个点,m 条边。问是否能把点分成三个集合,每个集合不为空,每个集合内部的点之间不能有连边,一个点必须与其他不在该集合的所有点要有连边。
解题思路:
首先分成三个集合。可以把与 1 号点没有连边的点分成集合E1,然后挑一个不在E1中的点,把与其没有连边的点分成集合E2,剩下的点分成E3。这三个集合不能为空。最后判断一个点必须与其他不在该集合的所有点要有连边这个条件即可。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #include <iostream> #include <cstdio> #include <vector> #define ll long long using namespace std; const int N = 1e6 + 5; int n, m, v[N]; vector <int> V[N]; int a[3]; int x[N], y[N]; int main() { scanf("%d%d", &n, &m); for(int i = 0; i < m; i++){ scanf("%d%d", &x[i], &y[i]); V[x[i]].push_back(y[i]); V[y[i]].push_back(x[i]); } for(int i = 1; i <= n; i++) v[i] = 1; for(int i = 0; i < V[1].size(); i++){ int y = V[1][i]; if(v[y] == 1) v[y] = 2; } for(int i = 1; i <= n; i++){ if(v[i] == 2){ for(int j = 0; j < V[i].size(); j++){ int y = V[i][j]; if(v[y] == 2) v[y] = 3; } break; } } for(int i = 1; i <= n; i++) a[v[i] - 1] ++; for(int i = 0; i < m; i++){ if(v[x[i]] == v[y[i]]) { printf("-1\n"); return 0; } } if(a[0] * a[1] + a[0] * a[2] + a[1] * a[2] != m || a[0] == 0 || a[1] == 0 || a[2] == 0){ printf("-1\n"); return 0; } for (int i = 1; i <= n; i++) { printf("%d ", v[i]); } return 0; }
|