[CF1296F] Berland Beauty
[CF1296F] Berland Beauty
题意
给你一颗大小为 \(n\) 的无根树,树边的边权尚未确定。现在你从 \(m\) 个人中得知在 \((u,v)\) 这条路径(最短路径)上的最小边权为 \(w\)。请你构造一种方案满足这 \(m\) 个人的条件,如果不存在,请输出 \(-1\)。
分析
我们显然可以先把边权按照从小到大排序,而后构造一种最优方案即把这条路径上的所有边都赋值为 \(w\)。这样我们可以使得每条路径上的最小值都尽可能满足题面的要求。而后我们检验是否合法。使用 LCA 维护即可。
代码
#includebitsstdc++.h
using namespace std;
const int N=1e4+7;
struct node{int u,v,w;}a[N];
int f[N][50];
int head[N],to[N],nxt[N];
int fat[N];
int dis[N],dep[N];
int cnt;
int n,m;
int num[N];
int w[N];
void add(int u,int v){
cnt++;to[cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
}
int xx;
void dfs(int x,int fa){
++xx;
if (xx 1e6) exit(0);
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa) continue;
num[y]=(i+1)2;
dep[y]=dep[x]+1;fat[y]=x;dfs(y,x);
}
}
void init(){
for(int i=1;i=n;i++) f[i][0]=fat[i];
for(int j=1;j=20;j++){
for(int i=1;i=n;i++){
f[i][j]=f[f[i][j-1]][j-1];
}
}
}
int lca(int x, int y) {
if (dep[x] dep[y])
swap(x, y);
if (dep[x] != dep[y]) {
for (int i = 20; i = 0; i--)
if (dep[f[x][i]] dep[y])
x = f[x][i];
x = f[x][0];
}
if (x == y)
return x;
for (int i = 20; i = 0; i--)
if (f[x][i] != f[y][i])
x = f[x][i], y = f[y][i];
return f[x][0];
}
void modify(int u,int v,int val){
int _lca=lca(u,v);
while(u!=_lca) w[num[u]]=val,u=f[u][0];
while(v!=_lca) w[num[v]]=val,v=f[v][0];
}
int query(int u,int v){
int _lca=lca(u,v);
int res=0x3f3f3f3f;
while(u!=_lca) res=min(res,w[num[u]]),u=f[u][0];
while(v!=_lca) res=min(res,w[num[v]]),v=f[v][0];
return res;
}
int main(){
scanf(%d,&n);
for(int i=1;i=n-1;i++){
int x,y;
scanf(%d%d,&x,&y);
add(x,y),add(y,x);
}
dfs(1,0);
init();
scanf(%d,&m);
for(int i=1;i=m;i++){
scanf(%d%d%d,&a[i].u,&a[i].v,&a[i].w);
}
sort(a+1,a+1+m,[](const node a,const node b){return a.wb.w;});
for(int i=1;i=m;i++) printf(%dn,a[i].w);
for(int i=1;i=n;i++) printf(%dn,num[i]);
for(int i=1;i=m;i++) modify(a[i].u,a[i].v,a[i].w);
bool flag=0;
for(int i=1;i=m;i++){
printf(%d ,query(a[i].u,a[i].v));
if(query(a[i].u,a[i].v)!=a[i].w){flag=1;break;}
}
if(flag) printf(-1n);
else{
for(int i=1;i=n-1;i++){
printf(%d ,w[i]w[i]1);
}
printf(%dn,w[n-1]w[n-1]1);
}
return 0;
}