CF1338B Edge Weight Assignment (Thinking + dfs)

The thinking of this question is more ingenious, examining the nature of XOR.

First of all, we analyze the largest case. The analysis of this case is to consider which two paths must be the same. Then there is only one case, that is, there are multiple leaf nodes under a certain node. Because of this, there are only two paths between leaf nodes. , So the values ​​on these two paths must be equal. In other cases, it can be randomly placed to satisfy the meaning of the question, because we can choose any weight, so it can be constructed, so the values ​​on other paths can be different. This proves to be quite complicated, but it is clearly correct.

In addition, our analysis is the smallest, and here we need to use the property of XOR. According to the nature of XOR, we find that if the paths between all leaf nodes are even numbered, then only one is needed, because even number of the same value XOR Is 0

Once there is an odd path, then the answer is 3, that is, we can satisfy by filling in the three numbers 1 2 3, first of all the two numbers must not be satisfied, and secondly we find that 123 XOR is 0, and we can self arrangement.

Although many questions prove to be more complicated, they are still intuitive to think of, which is why many people do thinking questions so fast

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<vector>
using 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 in[N];
int p[N];
void add(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;
    for(int i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
            continue;
        dfs(j,tmp^1,u);
    }
}
int main(){
    int n;
    cin>>n;
    int i;
    memset(h,-1,sizeof h);
    for(i=1;i<n;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
        in[a]++;
        in[b]++;
    }
    int mi=1;
    int mx=n-1;
    for(i=1;i<=n;i++){
        if(in[i]==1){
            dfs(i,0,-1);
            break;
        }
    }
    for(i=1;i<=n;i++){
        if(in[i]==1&&p[i]==1){
            mi=3;
            break;
        }
    }
    for(i=1;i<=n;i++){
        int cnt=0;
        for(int j=h[i];j!=-1;j=ne[j]){
            int k=e[j];
            if(in[k]==1){
                cnt++;
            }
        }
        if(cnt>=2){
            mx=mx-cnt+1;
        }
    }
    cout<<mi<<" "<<mx<<endl;
}
View Code

 

Guess you like

Origin www.cnblogs.com/ctyakwf/p/12760359.html