小叙:图论一直是我的弱项,在这几场的cf中没到图论就被卡住,本博主一直在补图论方面的知识,希望下场cf能AC一道图论题。
/*
* @Author: NEFU_马家沟老三
* @LastEditTime: 2020-08-06 18:11:03
* @CSDN blog: https://blog.csdn.net/acm_durante
* @E-mail: [email protected]
* @ProbTitle: 树遍历+贪心
*/
#include
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define lowbit(x) ((x) & -(x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define mem(a, b) memset(a, b, sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const double PI = acos(-1.0);
const ll mod = 1e9 + 7;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
template<class T>inline void read(T &res)
{
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
int n;
const int N = 1e5+5;
int w[N],cnt[N];
struct edge
{
int to,id;//id为边的编号
};
ll s;
vector<edge>e[N];//邻接链表
//now是当前节点编号,front为now上一节点与now所连接边的编号
void dfs(int now,int front){
if(e[now].size()==1){
cnt[front] = 1;
}
for(auto x:e[now]){
int to = x.to ,id = x.id;
if(id == front) continue;
dfs(to,id);
if(front!=0) cnt[front]+=cnt[id];
}
}
struct node
{
ll e_w,cnt_e;
bool operator <(const node &A) const{
return e_w * cnt_e - e_w / 2 * cnt_e < A.e_w * A.cnt_e - A.e_w / 2 * A.cnt_e;
}
};
priority_queue<node>q;//优先队列
int main()
{
IOS
int t;
cin >> t;
while (t--)
{
cin >> n >> s;
rep(i,1,n) e[i].clear();
while(!q.empty()) q.pop();
mem(cnt,0);
rep(i,1,n-1) {
int x,y;
cin >> x >> y >> w[i];
e[x].push_back({y,i});
e[y].push_back({x,i});
}
dfs(1,0);
ll sum = 0;
ll ans = 0;
rep(i,1,n-1){
q.push({(ll)w[i],(ll)cnt[i]});
sum += w[i]*1ll*cnt[i];
}
while(sum > s){
ans++;
ll ww = q.top().e_w, cc= q.top().cnt_e;
q.pop();
q.push({ww/2,cc});
sum = sum - cc*(ww) + cc*(ww/2);
}
cout << ans << '\n';
}
return 0;
}
/*
* @Author: NEFU_马家沟老三
* @LastEditTime: 2020-08-06 18:13:47
* @CSDN blog: https://blog.csdn.net/acm_durante
* @E-mail: [email protected]
* @ProbTitle:
*/
#include
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define lowbit(x) ((x) & -(x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define mem(a, b) memset(a, b, sizeof(a))
const double PI = acos(-1.0);
const int N = 2e5+5;
struct Edge
{
int v,next,w;
}e[N];
int head[N>>1];
int cnt;
void add(int u,int v,int w){
e[++cnt].v = v;
e[cnt].w = w;
e[cnt].next = head[u];
head[u] = cnt;
}//链式前向星
struct node
{
ll w,cnt;
bool operator<(const node &A)const{
return cnt * w - cnt * (w>>1) < A.cnt * A.w - A.cnt * ( A.w>>1 );
}
};
ll sum = 0;
priority_queue<node>q;
int dfs(int u,int fa){
int u_cnt = 0;//以当前节点为根的子树中节点的个数
for(int i = head[u]; ~i ; i = e[i].next){
int v = e[i].v , w = e[i].w;
if(v == fa) continue;
int son_cnt = dfs(v,u); //v为子树子节点个数
q.push({(ll)w,(ll)son_cnt});//存入优先队列
sum += son_cnt * 1ll * w;
u_cnt += son_cnt;
}
return u_cnt ? u_cnt : 1;//u_cnt为0则是叶子,需要返回1
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t--){
int n; ll s;
cnt = 0;//链式前向星pos
sum = 0;
mem(head,-1);
while(!q.empty()) q.pop();
cin >> n >> s;
rep(i,1,n - 1){
int u,v,w;
cin >> u >> v >> w;
add(u,v,w);
add(v,u,w);
}
dfs(1,-1);
ll ans = 0;
while(sum > s){
++ans;
ll w = q.top().w , c = q.top().cnt;
q.pop(),q.push({w>>1,c});
sum = sum - c * w + c * (w>>1);
}
cout << ans << '\n';
}
return 0;
}