CF 1399E2. Weights Division (hard version) (枚举+贪心)
题目链接:传送门
题目思路:题目相对于easy version 添加了一个cost条件,即w[i]/=2,不再是一次move,而是cost[i]次move(cost[i] ==1 or 2 ) 。 根据easy version贪心的思想,可以对于cost=1 和 cost=2 的两种边分别构造一个最优的move序列(可以得到当前最大的贡献值),然后枚举cost=1 的move 次数得到总贡献值,然后二分cost = 2 的move序列即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 typedef pair<int,int> pii; 5 typedef pair<LL,LL> pLL; 6 #define pb push_back 7 #define mk make_pair 8 #define fi first 9 #define se second 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 const int N=4e6+5; 12 const int inf=0x3f3f3f3f; 13 LL read() 14 { 15 LL x=0,f=1; 16 char ch=getchar(); 17 while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } 18 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 19 return f*x; 20 } 21 struct edge 22 { 23 int v,w,c; 24 edge(){} 25 edge(int vv,int ww,int cc){ v=vv; w=ww; c=cc; } 26 }; 27 vector<edge> e[N]; 28 struct node{ 29 LL x,id; 30 node(){} 31 node(LL xx,LL ii){ x=xx; id=ii; } 32 friend bool operator < (node X,node Y) 33 { 34 return X.x<Y.x; 35 } 36 }; 37 priority_queue<node> q1,q2; 38 LL cnt[N],w[N],n,s,s1[N],s2[N],c[N]; 39 void dfs(int u,int pre) 40 { 41 if(e[u].size()>1) cnt[u]=0; 42 else cnt[u]=1; 43 for(int i=0;i<e[u].size();i++) 44 { 45 edge x=e[u][i]; 46 int v=x.v; 47 if(v==pre) continue; 48 dfs(v,u); 49 w[v]=x.w; 50 c[v]=x.c; 51 cnt[u]+=cnt[v]; 52 } 53 } 54 void init() 55 { 56 for(int i=1;i<=n;i++) e[i].clear(); 57 while(!q1.empty()) q1.pop(); 58 while(!q2.empty()) q2.pop(); 59 } 60 int main() 61 { 62 int T=read(); 63 while(T--) 64 { 65 init(); 66 n=read(),s=read(); 67 for(int i=1;i<n;i++) 68 { 69 int x=read(),y=read(),z=read(),k=read(); 70 e[x].pb(edge(y,z,k)); 71 e[y].pb(edge(x,z,k)); 72 } 73 dfs(1,0); 74 LL res=0; 75 for(int i=2;i<=n;i++) 76 res+=1LL*w[i]*cnt[i]; 77 for(int i=2;i<=n;i++) 78 if(c[i]==1) q1.push(node(1LL*cnt[i]*(w[i]-w[i]/2),i)); 79 else q2.push(node(1LL*cnt[i]*(w[i]-w[i]/2),i)); 80 int t1=0,t2=0; 81 LL tmp=0; 82 while(!q1.empty()) 83 { 84 node t=q1.top(); 85 q1.pop(); 86 tmp+=t.x; 87 s1[++t1]=tmp; 88 w[t.id]/=2; 89 if(w[t.id]) q1.push(node(1LL*cnt[t.id]*(w[t.id]-w[t.id]/2),t.id)); 90 } 91 tmp=0; 92 while(!q2.empty()) 93 { 94 node t=q2.top(); 95 q2.pop(); 96 tmp+=t.x; 97 s2[++t2]=tmp; 98 w[t.id]/=2; 99 if(w[t.id]) q2.push(node(1LL*cnt[t.id]*(w[t.id]-w[t.id]/2),t.id)); 100 } 101 102 int ans=inf; 103 res-=s; 104 /* 105 printf("res = %lld\n",res); 106 printf("s1: "); for(int i=0;i<=t1;i++) printf("%lld%c",s1[i],i==t1?'\n':' '); 107 printf("s2: "); for(int i=0;i<=t2;i++) printf("%lld%c",s2[i],i==t2?'\n':' '); 108 */ 109 for(int i=0;i<=t1;i++) 110 { 111 LL x=res-s1[i]; 112 int j=lower_bound(s2,s2+t2+1,x)-s2; 113 if(j>t2) continue; 114 ans=min(ans,i+2*j); 115 } 116 printf("%d\n",ans); 117 } 118 return 0; 119 }