codeforces(D. Kuroni and the Celebration)交互题

原题链接

给定一棵树
需要每次询问两个点
然后读取这两个点的lca
问这棵树的根节点是?
最多n/2次查询

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;

struct node
{
    
    
    int to,next;
}q[20005];
int head[20005],cnt=1;
int e[2000];

void add(int x,int y)
{
    
    
    q[cnt].to=y;
    q[cnt].next=head[x];
    head[x]=cnt++;
}
int main()
{
    
    
    memset(head,-1,sizeof(head));
    int n,a,b;
    cin>>n;
    for(int i=1;i<=n-1;i++)
    {
    
    
        cin>>a>>b;
        add(a,b);add(b,a);
        e[a]++;e[b]++;
    }
    stack<int> st;
    for(int i=1;i<=n;i++)
    {
    
    
        if(e[i]==1)
        {
    
    st.push(i);}
    }
    //int ex=(n%2==0)?0:1;
    for(int i=1;i<=n/2;i++)
    {
    
    
        int f;
        int u=st.top();st.pop();
        int v=st.top();st.pop();
        cout<<"? "<<u<<" "<<v<<endl;
        fflush(stdout);
        cin>>f;
        if(f==u||f==v)
        {
    
    cout<<"! "<<f<<endl;break;}
        if(n%2!=0)
        {
    
    
            if(i==n/2)
            {
    
    
                for(int i=1;i<=n;i++)
                {
    
    
                    if(e[i]>1)
                    {
    
    cout<<"! "<<i<<endl;break;}
                }
                break;
            }
        }
        for(int i=head[u];i!=-1;i=q[i].next)
        {
    
    
            e[q[i].to]--;
            if(e[q[i].to]==1)
            {
    
    st.push(q[i].to);}
        }
        for(int i=head[v];i!=-1;i=q[i].next)
        {
    
    
            e[q[i].to]--;
            if(e[q[i].to]==1)
            {
    
    st.push(q[i].to);}
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/105522592