列表

详情


NC201102. Fire

描述

lives on a tree with vertices. The vertices are labelled as and is in vertex . Each vertex has a temperature. On the morning of each day after day 0, the temperature of each vertex decreases by . The temperature doesn't decrease on day 0. On the afternoon of each day, can travel to an adjacent vertex, provided that he is at a vertex with positive temperature and his destination vertex has a non-negative temperature. On the evening of each day, if the temperature is higher than or equal to , can cast magic which increases the temperature of the vertex he is in by . For each pair of adjacent vertices and , can travel from vertex to vertex at most once (and from to at most once). He can choose not to travel and stay in the current vertex.

wants to cast his magic on each vertex exactly once. He also tries to stay at vertex as long as possible, before traveling to any other city. Given the temperature of each vertex right before the morning of the day , on which day must prepare for departing? If prepares on day , he can cast his magic on that day and will make his first move on day . If he cannot cast his magic on each vertex exactly once even if he prepares for departing on the day , output .

输入描述

The first line contains two integers  and  ().
Each of the next lines contains two integers and , indicating an edge between vertices and ().
The (n+1)-th line contains n integers --- the temperature of vertex i right before the morning of day ().
It's guaranteed that the input is a tree structure.

输出描述

If he cannot cast his magic on each vertex exactly once, output .
Otherwise, output a single integer --- he must prepare for departing from vertex on day . Day is the day after day , and so on.

示例1

输入:

3 1
1 2
1 3
4 3 5

输出:

1

示例2

输入:

3 1
1 2
1 3
2 10 10

输出:

-1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 185ms, 内存消耗: 27460K, 提交时间: 2020-01-14 22:38:16

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>

#include <algorithm>
#include <random>
#include <bitset>
#include <queue>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <chrono>
#include <iostream>
#include <limits>
#include <numeric>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

template <class T>
istream& operator>>(istream& is, vector<T>& v) {
  for (T& x : v)
    is >> x;
  return is;
}

ostream& operator<<(ostream& os, const pair<char, int>& unit) {
  return os << unit.first << "^" << unit.second;
}

template <class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
  if (!v.empty()) {
    os << v.front();
    for (int i = 1; i < v.size(); ++i)
      os << ' ' << v[i];
  }
  return os;
}

const int N = 100010;

int n, k;
int a[N], s[N];
ll x[N], y[N];
vector<int> g[N];
vector<pair<pair<ll, int>, int>> greedy[N];

void dfs(int u) {
  s[u] = 1;
  for (int v : g[u])
    if (!s[v]) {
      dfs(v);
      s[u] += s[v];
      greedy[u].emplace_back(make_pair(x[v] - 1, s[v] * 2), v);
    }
  sort(greedy[u].begin(), greedy[u].end(), [&](const pair<pair<ll, int>, int>& lhs, const pair<pair<ll, int>, int>& rhs) { return rhs.first.first - lhs.first.second > lhs.first.first - rhs.first.second; });
  int d = greedy[u].size();
  vector<ll> dp;
  dp.push_back(numeric_limits<ll>::max());
  int pre = 0;
  x[u] = a[u] + min(k - 2 * s[u], 0);
  for (const auto& pr : greedy[u]) {
    x[u] = min(x[u], pr.first.first - pre);
    dp.push_back(min(dp.back(), pr.first.first - pre));
    pre += pr.first.second;
  }
  if (d) {
    vector<ll> suf(d + 1);
    suf[d] = numeric_limits<ll>::max();
    for (int i = d - 1; i >= 0; --i)
      suf[i] = min(suf[i + 1] - greedy[u][i].first.second, greedy[u][i].first.first);
    y[u] = numeric_limits<ll>::min();
    pre = 0;
    for (int i = 0; i < d; ++i) {
      int v = greedy[u][i].second;
      //cerr << k << ' ' << (s[u] - s[v]) << ' ' << d << '\n';
      //cerr << "=> " << v << ": " << (y[v] - 2 * (s[u] - s[v] - 1) - 1) << ' ' << (suf[i + 1] - pre) << ' ' << dp[i] << ' ' << a[u] << ' ' << (a[u] + k - 2 * (s[u] - s[v])) << '\n';
      y[u] = max(y[u], min({y[v] - 2 * (s[u] - s[v] - 1) - 1, suf[i + 1] - pre, dp[i], (ll)a[u], a[u] + k - 2LL * (s[u] - s[v])}));
      pre += greedy[u][i].first.second;
    }
  } else
    y[u] = a[u];
}

int main() {
#ifdef LBT
  freopen("test.in", "r", stdin);
  int nol_cl = clock();
#endif
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  cin >> n >> k;
  for (int rep = 1; rep < n; ++rep) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int i = 1; i <= n; ++i) cin >> a[i];
  dfs(1);
//  cerr << y[1] << '\n';
  cout << max(-1LL, y[1]) << '\n';

#ifdef LBT
  LOG("Time: %dms\n", int ((clock()
          -nol_cl) / (double)CLOCKS_PER_SEC * 1000));
#endif
  return 0;
}

C++ 解法, 执行用时: 90ms, 内存消耗: 12980K, 提交时间: 2022-07-14 23:47:27

#include<cstdio>
#include<algorithm>
using namespace std;
int n,nex[200001],fir[100001],sto[200001],ui,vi,tot,fa[100001],sz[100001],cnt;
long long f[200001][2],a[200001],k,pre[200001],las[200001],b[200001],s,ans;
struct node{long long v;int num;};
node c[200001];
bool cmp(node aa,node bb){return(aa.v>bb.v);}
void addbian(int aa,int bb)
{
	tot++;
	sto[tot]=bb;
	nex[tot]=fir[aa];
	fir[aa]=tot;
}
long long getmin(long long aa,long long bb)
{
	if(aa<bb)return(aa);
	else return(bb);
}
long long getmax(long long aa,long long bb)
{
	if(aa<bb)return(bb);
	else return(aa);
}
void dfs(int x)
{
	int aa=fir[x];
	sz[x]=1;
	while(aa!=0)
	{
		if(sto[aa]!=fa[x])
		{
			fa[sto[aa]]=x;
			dfs(sto[aa]);
			sz[x]=sz[x]+sz[sto[aa]]; 
		}
		aa=nex[aa];
	}
	f[x][0]=getmin(a[x],a[x]+k-2*sz[x]);
	f[x][1]=a[x];
	cnt=0;
	aa=fir[x];
	while(aa!=0)
	{
		if(sto[aa]!=fa[x])
		{
			cnt++;
			c[cnt].num=sto[aa];
			c[cnt].v=f[sto[aa]][0]-2*(sz[x]-sz[sto[aa]]-1)-1;
		}
		aa=nex[aa];
	}
	if(cnt!=0)
	{
		sort(c+1,c+1+cnt,cmp);
		las[cnt+1]=1000000000000000000;
		pre[0]=1000000000000000000;
		s=0;
		for(int i=1;i<=cnt;i++)
		{
			b[i]=c[i].v+2*s;
			s=s+sz[c[i].num];
			pre[i]=getmin(pre[i-1],b[i]);
			f[x][0]=getmin(f[x][0],b[i]);
		}
		f[x][1]=-10000000000;
		for(int i=cnt;i>=1;i--)las[i]=getmin(las[i+1],b[i]);
		for(int i=1;i<=cnt;i++)f[x][1]=getmax(f[x][1],getmin(getmin(f[c[i].num][1]-2*(sz[x]-sz[c[i].num]-1)-1,a[x]+k-2*(sz[x]-sz[c[i].num])),getmin(pre[i-1]+2*sz[c[i].num],las[i+1])));
		f[x][1]=getmin(f[x][1],a[x]);
	}
}
int main()
{
	scanf("%d%lld",&n,&k);
	for(int i=1;i<=n;i++)fir[i]=0;
	tot=0;
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&ui,&vi);
		addbian(ui,vi);
		addbian(vi,ui);
	}
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	fa[1]=1;
	dfs(1);
	ans=getmax(f[1][0],f[1][1]);
	printf("%d\n",getmax(-1,ans));
}

上一题