Submission #1365839

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

const int MAXN = 5e3 + 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...