NOIP2023 国庆集训 A 组 Day4

T1:

题意:石子合并板子就是改了一下

思路:优先队列,注意读题与开unsigned long long

T2:

思路:

  1. 二分枚举ans,O(n)查询
  2. dfs扫树,记录路径上最大wi即可,再排个序
AC代码1
 #include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n,m,W,vis[N],cnt,head[N << 1],a[N];
struct edge{
	int to,next,val;
}e[N << 1];
void add_edge(int u,int v,int w){
	e[++cnt].next = head[u];
	e[cnt].to = v;
	e[cnt].val = w;
	head[u] = cnt;
}
bool check(int x){
	memset(vis,0,sizeof(vis));
	LL s = 0;
	vis[1] = 1;
	queue<int> q;
	q.push(1);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i = head[u];i;i = e[i].next){
			if(!vis[e[i].to] && e[i].val <= x){
				s += a[e[i].to];
				q.push(e[i].to);
				vis[e[i].to] = 1;
			}
		}
		if(s >= W) break;
	}
	if(s >= W) return true;
	else return false;
}
int main(){
	freopen("aia_iai.in","r",stdin);
	freopen("aia_iai.out","w",stdout);
	cin >> n >> W;
	for(int i = 2;i <= n;i++) cin >> a[i];
	for(int i = 1;i < n;i++){
		int u,v,w;
		cin >> u >> v >> w;
		add_edge(u,v,w);
		add_edge(v,u,w);
	}
	int l = 1,r = 1e9;
	while(l <= r){
		int mid = (l + r) >> 1;
		if(!check(mid)) l = mid + 1;
		else r = mid - 1;
	}
	cout << l;
	return 0;
}
AC代码2

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
LL n,W,a[N],head[N << 1],cnt;
struct node{
	LL a,b;
	const bool operator <(const node &c) const{
		return a < c.a;
	}
}dot[N];
struct edge{
	LL next,to,val;
}e[N << 1];
void add_edge(int u,int v,int w){
	e[++cnt].next = head[u];
	e[cnt].to = v;
	e[cnt].val = w;
	head[u] = cnt;
}
void dfs(LL u,LL fa,LL dis){
	dot[u].a = dis;
	for(int i = head[u];i;i = e[i].next){
		LL v = e[i].to;
		if(v == fa) continue;
		dfs(v,u,max(dis,e[i].val));
	}
}
int main(){
	freopen("aia_iai.in","r",stdin);
	freopen("aia_iai.out","w",stdout);
	cin >> n >> W;
	for(int i = 2;i <= n;i++){
		cin >> a[i];
		dot[i].b = i;
	}
	for(int i = 1;i <= n - 1;i++){
		LL u,v,w;
		cin >> u >> v >> w;
		add_edge(u,v,w);
		add_edge(v,u,w); 
	}
	dfs(1,0,0);
	sort(dot + 2,dot + n + 1);
	LL now = 0;
	for(int i = 2;i <= n;i++){
		now += a[dot[i].b];
		if(now >= W){
			cout << dot[i].a;
			return 0;
		}
	}
	return 0;
} 
posted @ 2023-10-05 21:58  LouYW07  阅读(14)  评论(0)    收藏  举报