专栏文章
题解:P2977 [USACO10JAN] Cow Telephones G
P2977题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min4b2ue
- 此快照首次捕获于
- 2025/12/01 20:20 3 个月前
- 此快照最后确认于
- 2025/12/01 20:20 3 个月前
现有题解的写法好像都和我不太一样,所以写一篇题解。
首先找一个非叶子节点作为这棵树的根节点,然后考虑后序遍历贪心。
设 为节点 的来自子树的所有配对请求数,该节点可以组成的配对数 。
如果还有剩余且 ,则 节点可以再往上多上传一个请求 ,否则 。
最后的答案就是 。
代码:
CPP#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
int n,k,fa[N],fwd[N];
vector<int> order;
vector<int> G[N];
void solve(){
cin>>n>>k;
for(int i=1;i<n;i++){
int u,v; cin>>u>>v;
G[u].push_back(v),G[v].push_back(u);
}
int rt=1;
for(int i=1;i<=n;i++) if(G[i].size()>1) {
rt=i; break;
}
memset(fa,-1,sizeof(fa));
stack<int> stk;
stk.push(rt),fa[rt]=0;
while(!stk.empty()){
int u=stk.top(); stk.pop();
order.push_back(u);
for(auto v:G[u]) if(fa[v]==-1) fa[v]=u,stk.push(v);
}
reverse(order.begin(),order.end());
ll ans=0;
for(auto u:order){
int s=0;
for(auto v:G[u]) if(v!=fa[u]) s+=fwd[v];
if(u!=rt&&(int)G[u].size()==1) s++;
int m=min(s/2,k),f=0;
if(s-2*m>=1&&m<k) f=1;
ans+=m,fwd[u]=f;
}
return cout<<ans<<"\n",void();
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int T=1;
while(T--){
solve();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...