AtCoder-agc064_b.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. struct DSU {
  4. vector<int> parent, size;
  5. explicit DSU(int n) : parent(n), size(n, 1) { iota(parent.begin(), parent.end(), 0); }
  6. int find(int x) { return parent[x] == x ? x : parent[x] = find(parent[x]); }
  7. bool unite(int a, int b) {
  8. a = find(a); b = find(b);
  9. if (a == b) return false;
  10. if (size[a] < size[b]) swap(a, b);
  11. parent[b] = a; size[a] += size[b];
  12. return true;
  13. }
  14. };
  15. struct Edge { int u, v; char color; };
  16. int main() {
  17. ios::sync_with_stdio(false);
  18. cin.tie(nullptr);
  19. int n, m;
  20. cin >> n >> m;
  21. vector<Edge> edges(m);
  22. for (Edge &e : edges) {
  23. cin >> e.u >> e.v >> e.color;
  24. --e.u; --e.v;
  25. }
  26. string wanted;
  27. cin >> wanted;
  28. DSU dsu(n);
  29. vector<char> chosen(m, false), satisfied(n, false);
  30. vector<vector<pair<int, int>>> outgoing(n);
  31. for (int id = 0; id < m; ++id) {
  32. Edge e = edges[id];
  33. bool good_u = wanted[e.u] == e.color;
  34. bool good_v = wanted[e.v] == e.color;
  35. if (good_u && good_v && dsu.unite(e.u, e.v)) {
  36. chosen[id] = true;
  37. satisfied[e.u] = satisfied[e.v] = true;
  38. } else if (good_u != good_v) {
  39. int from = good_u ? e.v : e.u;
  40. int to = good_u ? e.u : e.v;
  41. outgoing[from].push_back({to, id});
  42. }
  43. }
  44. queue<int> queue;
  45. for (int v = 0; v < n; ++v) if (satisfied[v]) queue.push(v);
  46. while (!queue.empty()) {
  47. int u = queue.front();
  48. queue.pop();
  49. for (auto [v, id] : outgoing[u]) {
  50. if (satisfied[v]) continue;
  51. satisfied[v] = true;
  52. chosen[id] = true;
  53. dsu.unite(u, v);
  54. queue.push(v);
  55. }
  56. }
  57. if (find(satisfied.begin(), satisfied.end(), false) != satisfied.end()) {
  58. cout << "No\n";
  59. return 0;
  60. }
  61. for (int id = 0; id < m; ++id) {
  62. if (!chosen[id] && dsu.unite(edges[id].u, edges[id].v)) chosen[id] = true;
  63. }
  64. cout << "Yes\n";
  65. for (int id = 0; id < m; ++id) if (chosen[id]) cout << id + 1 << ' ';
  66. cout << '\n';
  67. return 0;
  68. }