URL:https://atcoder.jp/contests/abc299
目录
给出 N(1 <= N <= 2000)个点和 M 条边的一个无向图,要求用白色和黑色对这个图染色。
满足下面两个条件,则输出 Yes 和各点的颜色,否则输出 No:
这道题的坑点在于,题目没有很清楚地说明,只要有一个黑色点与 p 最短句路为 d 即可。因此很容易误认为所有距离 p 为 d 的点都要染黑。
搞清楚这点思路就很明确了,对于每个要求(p,d),bfs 把所有最短距离小于 d 的点都染成白色;
再次 bfs,判断是否有一个距离为 d 的且不为白色的点,有则 return true,否则这个要求不能满足,输出 No。
- #include "bits/stdc++.h"
-
- int n, m, dis[2003], ans[2003];
- std::vector <int> g[2003];
-
- struct K {
- int p, d;
- }tmp[2003];
-
- void white(int s, int d) {
- for (int i = 1; i <= n; ++ i) dis[i] = INT_MAX;
-
- std::queue
int, int>> q; - q.push({s, 0});
- dis[s] = 0;
-
- while (!q.empty()) {
- auto o = q.front(); q.pop();
-
- int x = o.first, pre = o.second;
-
- for (auto &next : g[x]) {
- if (next == pre) continue;
- if (dis[next] > dis[x] + 1) {
- dis[next] = dis[x] + 1;
- q.push({next, x});
- }
- }
- }
-
- for (int i = 1; i <= n; ++ i) {
- if (dis[i] < d) ans[i] = 0;
- }
- }
-
- bool black(int s, int d) {
- for (int i = 1; i <= n; ++ i) dis[i] = INT_MAX;
-
- std::queue
int, int>> q; - q.push({s, 0});
- dis[s] = 0;
-
- while (!q.empty()) {
- auto o = q.front(); q.pop();
-
- int x = o.first, pre = o.second;
-
- for (auto &next : g[x]) {
- if (next == pre) continue;
- if (dis[next] > dis[x] + 1) {
- dis[next] = dis[x] + 1;
- q.push({next, x});
- }
- }
- }
-
- for (int i = 1; i <= n; ++ i) {
- if (dis[i] == d and ans[i] != 0) {
- ans[i] = 1;
- return true;
- }
- }
-
- return false;
- }
-
- signed main () {
- std::cin >> n >> m;
- for (int i = 1; i <= m; ++ i) {
- int x, y; std::cin >> x >> y;
- g[x].push_back(y);
- g[y].push_back(x);
- }
-
- for (int i = 1; i <= n; ++ i) ans[i] = -1;
-
- int k; std::cin >> k;
- for (int i = 1; i <= k; ++ i) {
- std::cin >> tmp[i].p >> tmp[i].d; // 题目保证:pi < pj [i < j]
- white(tmp[i].p, tmp[i].d);
- }
-
-
- bool flag = true;
- for (int i = 1; i <= k; ++ i) {
- int s = tmp[i].p, d = tmp[i].d;
- if (!black(s, d)) {
- flag = false;
- break;
- }
- }
-
- if (!flag) {
- std::cout << "No";
- } else {
- if (k == 0) ans[1] = 1;
- std::cout << "Yes\n";
- for (int i = 1; i <= n; ++ i)
- std::cout << (ans[i] == -1 ? 0 : ans[i]);
- }
-
- return 0;
- }