Comentário Problema Startup

por

Startup

Comentário escrito por João Pedro Castro

Podemos visualizar a hierarquia dessa empresa como um grafo, onde os vértices (funcionários) tem outros vértices se ligando à ele (os subordinados). Além da estrutura do grafo, para cada funcionário vamos guardar seu chefe, salário, e a quantidade de subordinados com os quais ele está insatisfeito. Também é necessário guardar a quantidade de funcionários insatisfeitos no total, chamaremos esse valor de f.

Após montar o grafo (feito com as arestas sendo: \text{chefe} \rightarrow \text{subordinado}), receber o chefe de cada um e o salário, para preencher a quantidade de insatisfações basta percorrer o grafo começando do vértice 1 e aumentando o valor de insatisfacoes[vertice] em uma unidade toda vez que salario[subordinado] > salario[vertice]” /></span><script type='math/tex'>salario[subordinado] > salario[vertice]</script>, quando isso acontecer, também aumente <span class='MathJax_Preview'><img data-recalc-dims= em 1 caso insatisfacoes[vertice] = 0, já que o estado do vertice vai mudar de satisfeito para insatisfeito.

Para todo funcionário i atualizado a ideia é checar se o “estado” (satisfeito ou insatisfeito) de seu chefe e dele mesmo (em relação ao seus subordinados) foram alterados, já que eles são os únicos com os quais isso pode ter acontecido. E isso pode ser feito com uma série de estruturas condicionais, que se resumem à:

  • (chefe insatisfeito antes com o funcionário) e (chefe satisfeito agora)
  • (chefe satisfeito antes com o funcionário) e (chefe insatisfeito agora)

Agora, para achar o valor de f (a resposta) atualizado, é só seguir o seguinte algoritimo:

  • Se i \neq 1 ~\&~ salario[i] \geq salario[chefe[i]] ~\&~ novoSalario > salario[chefe[i]]” /></span><script type='math/tex'>i \neq 1 ~\&~ salario[i] \geq salario[chefe[i]] ~\&~ novoSalario > salario[chefe[i]]</script>
<ul>
<li><span class='MathJax_Preview'><img data-recalc-dims=
  • Se insatisfacoes[chefe[i]] = 1 (novo chefe insatisfeito):
    • f++
  • Se não se: salario[i] > salario[chefe[i]] ~\&~ salario[chefe[i]] \geq novoSalario” /></span><script type='math/tex'>salario[i] > salario[chefe[i]] ~\&~ salario[chefe[i]] \geq novoSalario</script>
<ul>
<li><span class='MathJax_Preview'><img data-recalc-dims=
  • Se insatisfacoes[chefe[i]] = 0 (chefe satisfeito de novo):
    • f--
  • Para cada subordinado u de i:
    • Se salario[i] \geq salario[u] ~\&~ salario[u] > novoSalario” /></span><script type='math/tex'>salario[i] \geq salario[u] ~\&~ salario[u] > novoSalario</script>:
<ul>
<li><span class='MathJax_Preview'><img data-recalc-dims=
    • Se insatisfacoes[i] = 1 (novo chefe insatisfeito):
      • f++
  • Se não se: salario[u] > salario[i] ~\&~ novoSalario \geq salario[u]” /></span><script type='math/tex'>salario[u] > salario[i] ~\&~ novoSalario \geq salario[u]</script>:
<ul>
<li><span class='MathJax_Preview'><img data-recalc-dims=
  • Se insatisfacoes[i] = 0 (chefe satisfeito de novo):
    • f--
  • salario[i] = novoSalario
  • imprimir~f
  • Assim você também garante que os valores de insatisfacoes e f sempre permanecem atualizados. Segue a solução em C++:


    #include <bits/stdc++.h>
    using namespace std;
    vector<vector<int>> adj;
    vector<int> salario;
    vector<int> chefe;
    vector<int> insatisfacoes;
    int f;
    void dfs(int i) {
    for (auto u : adj[i]) {
    if (u == chefe[i]) continue;
    if (salario[u] > salario[i]) {
    if (insatisfacoes[i] == 0) f++;
    insatisfacoes[i]++;
    }
    dfs(u);
    }
    }
    int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, a;
    cin >> n;
    adj.resize(n+1);
    salario.resize(n+1);
    chefe.resize(n+1);
    insatisfacoes.resize(n+1);
    for (int i = 1; i <= n; i++) {
    cin >> chefe[i] >> salario[i];
    adj[chefe[i]].push_back(i);
    }
    dfs(1);
    cout << f << "\n";
    cin >> a;
    while (a–) {
    int i, novoSalario;
    cin >> i >> novoSalario;
    if (i != 1) {
    if ((salario[chefe[i]] >= salario[i]) and (novoSalario > salario[chefe[i]])) {
    insatisfacoes[chefe[i]]++;
    if (insatisfacoes[chefe[i]] == 1) f++;
    }
    else if ((salario[i] > salario[chefe[i]]) and (salario[chefe[i]] >= novoSalario)) {
    insatisfacoes[chefe[i]]–;
    if (insatisfacoes[chefe[i]] == 0) f–;
    }
    }
    for (auto u : adj[i]) {
    if ((salario[i] >= salario[u]) and (salario[u] > novoSalario)) {
    insatisfacoes[i]++;
    if (insatisfacoes[i] == 1) f++;
    }
    else if ((salario[u] > salario[i]) and (novoSalario >= salario[u])) {
    insatisfacoes[i]–;
    if (insatisfacoes[i] == 0) f–;
    }
    }
    cout << f << "\n";
    salario[i] = novoSalario;
    }
    }

    view raw

    startup.cpp

    hosted with ❤ by GitHub