Problem
求最少用多少边能覆盖整个树,给出每条边被覆盖的次数
Solution
- 挺巧妙的逆向思维,最大值就是边权和,然后尽可能对每个点周围的边合并,根据周围一圈的最大值与一圈和的关系计算并掉多少。
Code
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn=1e5+5;
int t,n,ans,du[maxn],mx[maxn],num;
void init()
{
memset(mx,0,sizeof(mx));
memset(du,0,sizeof(du));
ans=0;
}
int main()
{
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=1,u,v,w;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
du[u]+=w;
du[v]+=w;
mx[u]=max(mx[u],w);
mx[v]=max(mx[v],w);
ans+=w;
}
for(int i=1;i<=n;i++)
2*mx[i]>du[i]?ans-=du[i]-mx[i]:ans-=(du[i]>>1);
printf("Case #%d: %d\n", ++num, ans);
init();
}
return 0;
}