CodeForces - 1305D Kuroni and the Celebration (树结构)

🧖‍♀️ 🧖‍♀️ 🧖‍♀️

题意:给你一个树结构,每次可以询问两个结点的LCA,问你树的根。

每次找出两个度为1的结点查询,
(1)如果LCA等于某点,则由于两点度数为1,不是叶子结点就是根节点,由于一个叶子结点不可能为另一个叶子的祖先,则一个点为根结点,一个点为叶子
(2)否则这两个结点一定为两个叶子结点,将他们直接删除

还有就是删除的时候set的应用

//从叶子结点开始删除,直到最后剩下根结点 or 求出当前某一结点为叶子结点
set<int>mp[1111];
int ans[1111];
void solve()
{
    int n;cin>>n;
    rpp(i,n-1)
    {
        int u,v;cin>>u>>v;
        mp[u].insert(v);
        mp[v].insert(u);
    }
    
    while(1)
    {
        ans[0]=0;
        rpp(i,n)
            if(mp[i].size()==1) ans[++ans[0]]=i;
        cout<<"? "<<ans[1]<<" "<<ans[2]<<endl;
        fflush(stdout);
        int x;cin>>x;
        if(x==ans[1]||x==ans[2]) 
        {
            cout<<"! "<<x<<endl;
            return ;
        }
        //将该叶子结点删除
        //即将他在与他相连的父节点图中删除该点
        //然后将该点连接的边清空
        mp[*mp[ans[1]].begin()].erase(ans[1]);
        mp[ans[1]].clear();
        mp[*mp[ans[2]].begin()].erase(ans[2]);
        mp[ans[2]].clear();
        if(mp[x].empty())
        {
            cout<<"! "<<x<<endl;
            return ;
        }
    }
}
signed main()
{
    int T = 1;
    while (T--)
        solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值