社区讨论
为何枚举每个点作为根的后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 条回复,欢迎继续交流。
正在加载回复...