https://vjudge.net/problem/CodeForces-1296F
题目大意:给出一棵有
n
n
n个节点的无根树,对于
m
m
m个询问
(
u
i
,
v
i
,
d
i
)
(u_i,v_i,d_i)
(ui,vi,di)满足从
u
i
u_i
ui到
v
i
v_i
vi的路径上的边权的最小值是
d
i
d_i
di,如果可以满足的话输出
n
−
1
n-1
n−1条边的权值,要求
1
<
=
f
i
<
=
1
0
6
1<=f_i<=10^6
1<=fi<=106,否则输出
−
1
-1
−1。
思路:虽然是 F F F题,其实就是一个裸的暴力。依次处理 m m m个询问,找到从 u i u_i ui到 v i v_i vi的路径,然后把该路径上的边的权值取本身与 d i d_i di的最大值。然后再遍历一遍 m m m个询问,看 u i u_i ui到 v i v_i vi的路径上的边权的最小值是否等于 d i d_i di,若相等则说明有解,输出每条边的边权即可( 0 0 0可以改成范围内的任意一个值)。树上找任意两点的路径也比较简单,这里提供两种方法:(1)暴力,用二维数组 f a [ u ] [ v ] fa[u][v] fa[u][v]表示以 u u u为根时 v v v的父节点,一共需要 n n n次 d f s dfs dfs,复杂度 O ( n 2 ) O(n^2) O(n2);(2)用 f a [ v ] fa[v] fa[v]表示以 1 1 1为根时 v v v的父节点,只需 1 1 1次 d f s dfs dfs,但是求路径时需要求 L C A LCA LCA,因此复杂度为 O ( n l g n ) O(nlgn) O(nlgn)。以下代码采取第一种方法(懒得写第二种 o r z orz orz)。总复杂度 O ( n ∗ m a x ( n , m ) ) O(n*max(n,m)) O(n∗max(n,m))。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=5005;
struct Edge
{
int to,nxt;
}edge[maxn<<1];
int n,m,tot,root;
int head[maxn];
int x[maxn],y[maxn],fa[maxn][maxn],ans[maxn][maxn];
int u[maxn],v[maxn],d[maxn];
inline void addedge(int u,int v)
{
edge[++tot].to=v,edge[tot].nxt=head[u],head[u]=tot;
}
inline void dfs(int u,int f)
{
fa[root][u]=f;
for(int i=head[u],v;i;i=edge[i].nxt)
{
v=edge[i].to;
if(v!=f)
dfs(v,u);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d %d",&x[i],&y[i]);
addedge(x[i],y[i]),addedge(y[i],x[i]);
}
for(int i=1;i<=n;i++)
root=i,dfs(i,0);
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&u[i],&v[i],&d[i]);
int a=u[i],b=v[i];
int fb=fa[a][b];
while(fb!=a)
{
ans[fb][b]=ans[b][fb]=max(ans[fb][b],d[i]);
b=fb;
fb=fa[a][fb];
}
ans[fb][b]=ans[b][fb]=max(ans[fb][b],d[i]);
}
bool flag=1;
for(int i=0;i<m&&flag;i++)
{
int a=u[i],b=v[i];
int fb=fa[a][b];
int MIN=INF;
while(fb!=a)
{
MIN=min(ans[fb][b],MIN);
b=fb;
fb=fa[a][fb];
}
MIN=min(ans[fb][b],MIN);
if(MIN!=d[i])
flag=0;
}
if(flag)
{
for(int i=1;i<n;i++)
{
if(!ans[x[i]][y[i]])
ans[x[i]][y[i]]=1;
printf("%d ",ans[x[i]][y[i]]);
}
}
else
printf("-1\n");
return 0;
}