NC24609. [USACO 2011 Jan G]Bottleneck
描述
Locn: 1---2---3---4 <-- Pasture ID numbers C_i: 0 1 12 12 <-- Current number of cows M_i: 5 8 3 <-- Limits on path traversal; field 1 has no limit since it has no exit The solution is as follows; the goal is to move cows to field 1:
Tree: 1---2---3---4
t=0 0 1 12 12 <-- Initial state t=1 5 4 7 9 <-- field 1 has cows from field 2 and 3 t=2 10 7 2 6 t=3 15 7 0 3 t=4 20 5 0 0 t=5 25 0 0 0 Thus, the answer is 25: all 25 cows can arrive at field 1 by time t=5.
输入描述
* Line 1: Two space-separated integers: N and K
* Lines 2..N: Line i (not i+1) describes field i with three space-separated integers: , , and
* Lines N+1..N+K: Line N+i contains a single integer:
输出描述
* Lines 1..K: Line i contains a single integer that is the maximum number of cows that can arrive at field 1 by time .
示例1
输入:
4 1 1 1 5 2 12 7 3 12 3 5
输出:
25
C++11(clang++ 3.9) 解法, 执行用时: 52ms, 内存消耗: 3168K, 提交时间: 2020-03-07 12:06:19
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <queue> typedef long long LL; using namespace std; const int N=100010; struct Query{LL t,res;int id;}ask[N]; bool cmp1(Query x,Query y){return x.t<y.t;} bool cmp2(Query x,Query y){return x.id<y.id;} struct Node{ LL t;int x;Node(LL t_=0,int x_=0){t=t_;x=x_;} friend bool operator<(Node a,Node b){return a.t>b.t;} }; priority_queue<Node>q; int fa[N],anc[N],lim[N]; LL cow[N],pass[N]; int Find(int x){ if(anc[x]==x)return x; return anc[x]=Find(anc[x]); } int n,Q; int main(){ scanf("%d%d",&n,&Q); for(int i=1;i<=n;i++) anc[i]=i; for(int i=2;i<=n;i++){ scanf("%d",&fa[i]); scanf("%lld",&cow[i]); scanf("%lld",&lim[i]); pass[fa[i]]-=lim[i]; pass[i]+=lim[i]; } for(int i=1;i<=Q;i++){ scanf("%lld",&ask[i].t); ask[i].id=i; }sort(ask+1,ask+Q+1,cmp1); for(int i=2;i<=n;i++) if(pass[i]>0){ LL t=cow[i]/pass[i]; q.push(Node(t,i)); } int p=1,x,tp; while(!q.empty()&&p<=Q){ while(p<=Q&&ask[p].t<=q.top().t) ask[p].res=cow[1]-pass[1]*ask[p].t,p++; if(anc[q.top().x]!=q.top().x){q.pop();continue;} x=q.top().x;tp=Find(fa[x]);cow[tp]+=cow[x]; pass[tp]+=pass[x];anc[x]=tp; if(pass[tp]>0){ LL t=cow[tp]/pass[tp]; q.push(Node(t,tp)); } q.pop(); }sort(ask+1,ask+Q+1,cmp2); for(int i=1;i<=Q;i++) printf("%lld\n",ask[i].res); return 0; }