Codeforces - Berland Beauty

题目链接:Codeforces - Berland Beauty


题目大意:就是给你很多树上点对之间边的min,问是否存在一组合法方案。

所以我们对于两组边有交的条件,只需要取max即可,因为要两个都满足。

因为n很小所以暴力修改即可,如果n比较大我们就需要 树剖+势能线段树 。

最后check一下min即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=5e3+10,inf=0x3f3f3f3f;
int n,v[N],f[N],dep[N],a[N],b[N],c[N],m,p[N],q[N];
vector<int> g[N];
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
void dfs(int x,int fa){
	dep[x]=dep[fa]+1;	f[x]=fa;
	for(auto to:g[x])	if(to!=fa)	dfs(to,x);
}
void change(int x,int y,int val){
	while(x!=y){
		if(dep[x]<dep[y])	swap(x,y);
		v[x]=max(v[x],val);	x=f[x];
	}
}
int get(int x,int y){
	int mi=inf;
	while(x!=y){
		if(dep[x]<dep[y])	swap(x,y);
		mi=min(mi,v[x]);	x=f[x];
	}
	return mi;
}
signed main(){
	cin>>n;
	for(int i=1;i<n;i++)	cin>>p[i]>>q[i],add(p[i],q[i]);
	dfs(1,1);	cin>>m;
	for(int i=1;i<=m;i++){
		cin>>a[i]>>b[i]>>c[i],change(a[i],b[i],c[i]);
	}
	for(int i=1;i<=m;i++)	
		if(get(a[i],b[i])!=c[i])	return puts("-1"),0;
	for(int i=1,res;i<n;i++){
		if(dep[p[i]]>dep[q[i]])	res=v[p[i]];
		else	res=v[q[i]];
		if(!res)	res=1;
		cout<<res<<' ';
	}
	return 0;
}
发布了553 篇原创文章 · 获赞 242 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104208749