Submission #1355373

#TimeUsernameProblemLanguageResultExecution timeMemory
1355373thuhienneTransport (COCI19_transport)C++20
0 / 100
0 ms0 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

#define re exit(0);

const int maxn = 100009;

int n,arr[maxn];
vector <pair <int,int>> adj[maxn];

ll res;
int sz[maxn];
bool del[maxn];

int countChild(int node,int par) {
	sz[node] = 1;
	for (pair <int,int> x : adj[node]) if (x.first != par && !del[x.first]) {
		sz[node] += countChild(x.first,node);
	}
	
	return sz[node];
}
int findCentroid(int node,int par,int n) {
	for (pair <int,int> x : adj[node]) if (x.first != par && !del[x.first] && sz[x.first] > n / 2) {
		return findCentroid(x.first,node,n);
	}
	return node;
}

//0:up,1:down
vector <pair <ll,bool>> cont[maxn];
bool cmp(pair <ll,bool> a,pair <ll,bool> b) {
	if (a.first != b.first) return a.first > b.first;
	return a.second < b.second;
}

void dfs_down(int node,int par,vector <pair <ll,bool>> & cont,ll curr,ll need) {
	cont.push_back({need,1});
	
	curr += arr[node];
	
	for (pair <int,int> x : adj[node]) if (x.first != par && !del[x.first]) {
		dfs_down(x.first,node,cont,max(0ll,curr - x.second),need + max(0ll,x.second - curr));
	}
}

void dfs_up(int node,int par,vector <pair <ll,bool>> & cont,ll minval,ll sum) {
	if (minval >= 0) cont.push_back({sum,0});
	
	for (pair <int,int> x : adj[node]) if (x.first != par && !del[x.first]) {
		dfs_up(x.first,node,cont,min(0ll,minval) + arr[x.first] - x.second,sum + arr[x.first] - x.second);
	}
}

void addres(int node) {
	
	vector <pair <ll,bool>> total;

	for (pair <int,int> x : adj[node]) if (!del[x.first]) {
		int child = x.first,w = x.second;
		
		cont[child].clear();
		
		dfs_down(child,node,cont[child],0,w);
		dfs_up(child,node,cont[child],arr[child] - w,arr[node] + arr[child] - w);
		
		for (pair <ll,bool> x : cont[child]) total.push_back(x);
		
		sort(cont[child].begin(),cont[child].end(),cmp);
		
	}
	
	total.push_back({arr[node],0});
	total.push_back({0,1});
	
	sort(total.begin(),total.end(),cmp);
	
//	for (pair <ll,bool> x : total) cout << x.first << " " << x.second << '\n';
	
	int cntup = 0;
	for (pair <ll,bool> x : total) {
		if (x.second == 0) cntup++;
		else res += cntup;
	}
	
	//tru cac thang xuat phat va ket thuc tai cung cay con
	res--;
	
	for (pair <int,int> x : adj[node]) if (!del[x.first]) {
		
		cntup = 0;
		for (pair <ll,bool> a : cont[x.first]) {
			if (a.second == 0) cntup++;
			else res -= cntup;
		}
		
	}

}

void solve(int node) {
	int cnt = countChild(node,0);
	int ct = findCentroid(node,0,cnt);
	
	addres(ct);
	
	del[ct] = 1;
	for (pair <int,int> x : adj[ct]) if (!del[x.first]) solve(x.first);
	
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(nullptr);
//  freopen(".inp","r",stdin);
//  freopen(".out","w",stdout);

	cin >> n;
	for (int i = 1;i <= n;i++) cin >> arr[i];
	for (int i = 1;i < n;i++) {
		int u,v,w;cin >> u >> v >> w;
		adj[u].push_back({v,w});
		adj[v].push_back({u,w});
	}
	
	solve(1);
//	addres(2);

	cout << res;

}
#Verdict Execution timeMemoryGrader output
Fetching results...