Submission #1365840

#TimeUsernameProblemLanguageResultExecution timeMemory
1365840julia_08Tour (BOI25_tou)C++20
0 / 100
35 ms94220 KiB
  #include <bits/stdc++.h>
  using namespace std;

  const int MAXN = 1e6 + 10;
  const int INF = 1e9;

  int vis[MAXN], edge[MAXN];

  pair<int, pair<int, int>> pai[MAXN]; // duas arestas "pai" do vértice

  set<pair<int, pair<int, int>>> adj[MAXN], inv[MAXN];
  // guardo o inv para poder desfazer adj depois

  bool cycle = false;

  vector<int> ans;

  void get_cycle(int v, int w, int i, int j){

    // vou de v para w (usando os pais) na ordem reversa,
    // depois adiciono i e j

    while(v != w){

      ans.push_back(pai[v].second.first);
      ans.push_back(pai[v].second.second);

      v = pai[v].first;

    }

    reverse(ans.begin(), ans.end());

    ans.push_back(i);
    ans.push_back(j);

  }

  void dfs(int v){

    // cout << "dfs at " << v << endl;
    vis[v] = 1;

    for(auto [c, x] : adj[v]){

      // cout << "looking at " << x.first << endl;

      // cout << "possible candidates: ";
      // for(auto [c2, x2] : adj[x.first]) cout << x2.first << " "; cout << endl;

      auto [u, i] = x;

      auto pos = adj[u].upper_bound(make_pair(c, make_pair(INF, INF)));

      while(pos != adj[u].end()){

        int w = pos->second.first;
        int j = pos->second.second;

        auto to_erase = *pos;

        // cout << v << " -> " << w << endl;

        if(!vis[w]){

          pai[w] = {v, {j, i}}; // preciso guardar as arestas que usei
          dfs(w);

        } else{

          // eba, encontrei um ciclo!
          if(!cycle) get_cycle(v, w, i, j);
          cycle = true;

        }

        adj[u].erase(to_erase);
        pos = adj[u].upper_bound(make_pair(c, make_pair(INF, INF)));

      }

      pos = adj[u].lower_bound(make_pair(c, make_pair(0, 0)));

      while(pos != adj[u].begin()){

        --pos;
        int w = pos->second.first;
        int j = pos->second.second;

        auto to_erase = *pos;

        // cout << v << " -> " << w << endl;

        if(!vis[w]){

          pai[w] = {v, {j, i}};
          dfs(w);

        } else{

          // eba, encontrei um ciclo!
          if(!cycle) get_cycle(v, w, i, j);
          cycle = true;

        }

        adj[u].erase(to_erase);
        pos = adj[u].lower_bound(make_pair(c, make_pair(0, 0)));

      }

    }

    for(auto [c, x] : inv[v]){
      auto [u, i] = x;
      adj[u].erase({c, {v, i}});
    } // agora que saí, n posso mais visitar esse vertice de novo

  }

  void solve(){

    int n, m; cin >> n >> m;

    cycle = false;
    ans.clear();

    for(int i=1; i<=n; i++){

      adj[i].clear(); inv[i].clear();
      vis[i] = 0;

    }

    for(int i=0; i<m; i++){

      int a, b, c; cin >> a >> b >> c;

      adj[a].insert({c, {b, i}});
      inv[b].insert({c, {a, i}});

      edge[i] = 0;

    }

    for(int i=1; i<=n; i++) if(!vis[i]) dfs(i);

    if(!cycle){
      cout << "NO\n";
      return;
    }

    cout << "YES\n";

    for(auto i : ans) edge[i] ++;

    while(edge[ans.back()] > 1){
      edge[ans.back()] --;
      ans.pop_back();
    }

    cout << (int) ans.size() << " ";

    for(auto i : ans) cout << i + 1 << " ";
    cout << "\n";

  }

  int main(){
    cin.tie(0)->sync_with_stdio(0);

    int t; cin >> t;

    while(t--){
      solve();
    }

    return 0;
  }
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...