社区讨论

为何枚举每个点作为根的后WA的更多了?

P15268「UTOI 1C」Delirium Of Aeons参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mlhvabgh
此快照首次捕获于
2026/02/11 18:08
上周
此快照最后确认于
2026/02/13 15:30
6 天前
查看原帖
原思路是不断试图合并叶子节点。只要叶节点的祖先有至少2个儿子就可以合并上去,导致连通块有至少两个出边
刚开始假设根是度数最多的点,可以得到20分
后来想试图枚举各个点作为根的情况,却扣的分更多了。为什么啊?
CPP
#include <bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define spq priority_queue<int,vector<int>,greater<int>>
#define endl "\n"
using namespace std;
vector<vector<int>> adj;
int dfs(int cur,int par,spq &pq){
    spq children;
    for (int i:adj[cur]){
        if (i==par) continue;
        children.push(dfs(i,cur,pq));
    }
    if (children.empty()) return 1;
    while (children.size()>1){
        int pqt=children.top();
        children.pop();
        pq.push(pqt);
    }
    return children.top()+1;
}
int n,m;
int rt(int root,int ans){
    spq pq;
    dfs(root,-1,pq);
    for (int i=n-m;i>=0&&pq.size()&&ans>2;){
        int pqt=pq.top();
        pq.pop();
        if (pqt>i) break;
        i-=pqt;
        ans--;
    }
    return ans;
}
int solve(){
    cin>>n>>m;
    if (m==1) return 0;
    adj=vector<vector<int>>(n+1);
    int root=-1,rootdeg=2;
    for (int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    int ans=0;
    for (int i=1;i<=n;i++){
        if (adj[i].size()==1) ans++;
        if (adj[i].size()>rootdeg) root=i,rootdeg=adj[i].size();
    }
    if (root==-1) return 2;
    int anss=1e18;
    // for (int i=1;i<=n;i++){
    //     if (adj[i].size()>=2){
    //         anss=min(anss,rt(i,ans));
    //     }
    // }
    anss=rt(root,ans); // 此时能得20分,但是使用上面注释的枚举代码就WA更多点了
    assert(anss<=rt(root,ans));
    assert(anss>=2);
    return anss;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin>>t;
    while (t--) cout<<solve()<<endl;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...