㊗️:☀️☃️☃️☃️☀️ • 1个月前
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
int n;
struct grow
{
long long a;
int b, c;
int bp; //max(b+cx,1)两者的相交点
void make() {
if (c == 0) {
b = max(b, 1);
}
else {
bp = (1 - b) / c;
if (c > 0 && (1 - b) % c ) bp++;
}
}
bool check(int startDay, int endDay) {
long long high = a;
if (c >= 0) {
if (startDay < bp && endDay < bp) return endDay - startDay + 1 >= high;
if (startDay < bp) {
high -= bp - startDay;
startDay = bp;
}
return (1ll * c * startDay + b + 1ll * c * endDay + b) >= (long double)high / (endDay - startDay + 1) * 2;
}
else {
if (endDay > bp && startDay > bp) return endDay - startDay + 1 >= high;
else if (endDay > bp) {
high -= endDay - bp;
endDay = bp;
}
return (1ll * c * startDay + b + 1ll * c * endDay + b) >= (long double)high / (endDay - startDay + 1) * 2;
}
}
}gl[100001];
struct info {
int index;
int day;
bool operator <(info i2) {
return day < i2.day;
}
}list[100001];
bool planed[100001]; //某个点是否已安排
int fa[100001];
bool check(int endday) {
//倒推算出各个点至少开始种的时间
for (int i = 1; i <= n; i++) {
int left = 0, right = endday;
while (left < right) { //二分查找种的第一天
int mid = (left + right) / 2 + 1;
if (gl[i].check(mid, endday)) left = mid;
else right = mid - 1;
}
if (left == 0) return false;
list[i].index = i;
list[i].day = left;
}
sort(list + 1, list + n + 1);
memset(planed, 0, sizeof planed);
int planday = 0;//已安排天数
for (int i = 1; i <= n; i++) {
int node = list[i].index;
while (!planed[node] && node)
{
planday++;
planed[node] = true;
node = fa[node];
}
if (planday > list[i].day) return false;
}
return true;
}
vector<int> map[100001];
void dfs(int node) {
for (int next : map[node]) if (next != fa[node]) {
fa[next] = node;
dfs(next);
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> gl[i].a >> gl[i].b >> gl[i].c;
gl[i].make();
}
for (int i = 0; i < n - 1; i++) {
int a, b;
cin >> a >> b;
map[a].push_back(b);
map[b].push_back(a);
}
dfs(1);
int left = 1, right = 1e9;
while (left < right) {
int mid = (left + right) / 2;
if (check(mid)) right = mid; //检查mid天能否完成任务
else left = mid + 1;
}
cout << left;
return 0;
}
评论:
请先登录,才能进行评论