codeforces 1305D - Kuroni and the Celebration (tree, node degree)

Subject to the effect:

There is known a tree of n nodes. We can ask LCA n / 2 (rounded down) once any two nodes (about what the LCA  https://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1/ ), we asked how to determine the root node.

n<=1e3

Problem-solving ideas:

Because the range of n Here, we consider n ^ 2 algorithms.

First, there is a conclusion: every time we asked two nodes of degree LCA 1 (u, v), if LCA = u or LCA = v, then the root is certainly LCA. This can be proved by contradiction. For u, v which is not a degree, then 1, this conclusion does not hold, because u, v LCA represents only one of which is u or v Who is more in the lower it.

So every time we enumerate any two leaf nodes (ie leaf nodes of degree point 1), if the two points come to LCA is being asked of one, then we quit. If not, we can delete the two leaves continue to ask repeated. This allows n / 2 times to complete interrogation and root node.

Here the degree of use of this concept, make plans when the degree thesis sometimes is a good starting point, there are similar topological sort of problem.

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;cin>>n;
    int deg[n];
    memset(deg,0,sizeof(deg));
    vector<vector<int>> gra(n);
    set<int> ms;
    for(int i=0;i<n-1;i++){
        int u,v;cin>>u>>v;
        u--;v--;
        deg[u]++;
        deg[v]++;
        gra[u].push_back(v);
        gra[v].push_back(u);
        ms.insert(i);
    }
    ms.insert(n-1);
    int l,r;
    l=r=-1;
    
    while(1){
            l=-1;r=-1;
            for(int i=0;i<n;i++){
                if(deg[i]==1){
                    if(l==-1)l=i;
                    else r=i;
                }
            }
            
            if(l==-1 || r==-1)break;
            printf("? %d %d\n",l+1,r+1);
            fflush(stdout);
            // cerr<<l<<" "<<r<<endl;
            
            int w;cin>>w;
            w--;
            if(w==l || w==r){
                printf("! %d\n",w+1);
                fflush(stdout);
                return 0;
            }
            deg[l]--;
            for(int i=0;i<(int)gra[l].size();i++){
                int nx=gra[l][i];
                deg[nx]--;
            }
            deg[r]--;
            for(int i=0;i<(int)gra[r].size();i++){
                int nx=gra[r][i];
                deg[nx]--;
            }
            
            ms.erase(l);
            ms.erase(r);
        }
    assert(ms.size());
    printf("! %d\n",*ms.begin()+1);
    fflush(stdout);
	return 0;
}

 

Published 161 original articles · won praise 3 · Views 9669

Guess you like

Origin blog.csdn.net/FrostMonarch/article/details/104668517