CF1338B Atribuição de peso da borda (pensamento + dfs)

O pensamento desta questão é mais engenhoso, examinando a natureza do XOR.

Antes de tudo, analisamos o maior caso. A análise deste caso é considerar quais dois caminhos devem ser os mesmos. Depois, há apenas um caso, ou seja, existem vários nós de folhas em um determinado nó. Por esse motivo, existem apenas dois caminhos entre os nós de folhas. , Portanto, os valores nesses dois caminhos devem ser iguais. Em outros casos, ele pode ser colocado aleatoriamente para satisfazer o significado da pergunta, porque podemos escolher qualquer peso, para que possa ser construído, para que os valores em outros caminhos possam ser diferentes. Isso prova ser bastante complicado, mas está claramente correto.

Além disso, nossa análise é a menor e, aqui, precisamos usar a propriedade XOR De acordo com a natureza do XOR, descobrimos que, se os caminhos entre todos os nós das folhas forem numerados, será necessário apenas um, porque um número par com o mesmo valor XOR É 0

Quando existe um caminho ímpar, a resposta é 3, ou seja, podemos satisfazer preenchendo os três números 1 2 3, primeiro os dois números não devem ser satisfeitos e, em segundo lugar, descobrimos que 123 XOR é 0 e podemos Organizar.

Embora muitas perguntas se mostrem mais complicadas, elas ainda são intuitivas, e é por isso que muitas pessoas pensam tão rápido nas perguntas.

#include <algorithm> 
#include <iostream> 
#include <cstring> 
#include <cstdlib> 
#include <cstdio> 
#include <cmath> 
#include < string > 
#include <map> 
#include <vector>
 usando o  namespace std; 
typedef long  long ll;
const  int N = 1e6 + 10 ;
const  int mod = 1e9 + 7 ;
int e [N], ne [N], h [N], idx;
int  em [N];
int p [N];
vazioadd ( int a, int b) { 
    e [idx] = b, ne [idx] = h [a], h [a] = idx ++ ; 
} 
void dfs ( int u, int tmp, int fa) { 
    p [u] = tmp;
    para ( int i = h [u]; i! = - 1 ; i = ne [i]) {
         int j = e [i];
        se (j == fa)
             continuar ; 
        dfs (j, tmp ^ 1 , u); 
    } 
} 
int main () {
     int n; 
    cin>> n;
    int i; 
    memset (h, - 1 , sizeof h);
    para (i = 1 ; i <n; i ++ ) {
         int a, b; 
        scanf ( " % d% d " , & a, & b); 
        adicione (a, b); 
        adicione (b, a); 
        em [a] ++ ;
        em [b] ++ ; 
    } 
    int mi = 1 ;
    int mx = n- 1 ;
    for (i = 1 ; i <= n; i ++ ) {
         if (em [i] == 1 ) { 
            dfs (i, 0 , - 1 );
            quebrar ; 
        } 
    } 
    para (i = 1 ; i <= n; i ++ ) {
         if ( em [i] == 1 && p [i] == 1 ) { 
            mi = 3 ;
            quebrar ; 
        } 
    } 
    para (i = 1 ; i <= n; i ++ ) {
         int cnt = 0 ;
        para ( int j = h [i]; j! = -1 ; j = ne [j]) {
             int k = e [j];
            if ( em [k] == 1 ) { 
                cnt ++ ; 
            } 
        } 
        if (cnt> = 2 ) { 
            mx = mx-cnt + 1 ; 
        } 
    } 
    cout << mi << "  " << mx << endl; 
}
Ver Código

 

Acho que você gosta

Origin www.cnblogs.com/ctyakwf/p/12760359.html
Recomendado
Clasificación