题解:
方法1: 走一遍dfs/bfs得到u->v的路径。每一个m,保证走过得边>=此最小值。再走一遍m,看路径的最小值是否是提供的。
#include <bits/stdc++.h> # define LL long long using namespace std; int n; int m; void bfs(int u, vector<pair<int,int>> &p, vector<vector<pair<int,int>>> &adj){ queue<int> q; q.push(u); while(!q.empty()){ int cur=q.front(); q.pop(); for(auto as:adj[cur]){ int v=as.first; if(v==p[cur].first) continue; int e=as.second; p[v].first=cur; p[v].second=e; q.push(v); } } } int main(){ scanf("%d", &n); vector<vector<pair<int,int>>> adj(n+1); for(int i=1;i<=n-1;++i){ int u,v; scanf("%d %d", &u, &v); adj[u].push_back(make_pair(v,i)); adj[v].push_back(make_pair(u,i)); } vector<vector<pair<int,int>>> pre(n+1,vector<pair<int,int>>(n+1)); for(int i=1;i<=n;++i){ pre[i][i]=make_pair(0,0); bfs(i,pre[i], adj); } scanf("%d", &m); vector<int> val(n,0); vector<vector<int>> query(m+1,vector<int>(3,0)); for(int i=1;i<=m;++i){ scanf("%d %d %d", &query[i][0], &query[i][1], &query[i][2]); } for(int i=1;i<=m;++i){ int u=query[i][0]; int v=query[i][1]; int f=query[i][2]; while(true){ int pree=pre[u][v].second; int prev=pre[u][v].first; val[pree]=max(val[pree],f); v=prev; if(v==u) break; } } for(int i=1;i<=m;++i){ int u=query[i][0]; int v=query[i][1]; int f=query[i][2]; int mx=1000000+10; while(true){ int pree=pre[u][v].second; int prev=pre[u][v].first; mx=min(mx,val[pree]); v=prev; if(v==u) break; } if(mx!=f){ printf("-1"); return 0; } } for(int i=1;i<=n-1;++i){ if(val[i]==0) printf("100 "); else printf("%d ", val[i]); } return 0; }
方法2:
LCA
#include <bits/stdc++.h> # define LL long long using namespace std; const int maxn=5000+10; int n; int m; int lg[maxn]; int depth[maxn]; int fa[maxn][22]; int edgenum[maxn]; int w[maxn]; struct Edge{ int to, next, idx; }e[maxn<<1]; int head[maxn]; int en; void add(int from, int to, int idx){ e[en].next=head[from]; e[en].to=to; e[en].idx=idx; head[from]=en; ++en; } void dfs(int u, int pre){ depth[u]=depth[pre]+1; fa[u][0]=pre; for(int i=1;i<=lg[depth[u]-1];++i){ fa[u][i]=fa[fa[u][i-1]][i-1]; } for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; int id=e[i].idx; if(v==pre) continue; edgenum[v]=id; dfs(v,u); } } int LCA(int p, int q){ if(depth[p]<depth[q]) swap(p,q); while(depth[p]>depth[q]){ p=fa[p][lg[depth[p]-depth[q]]]; } if(p==q) return p; for(int i=lg[depth[p]-1];i>=0;--i){ if(fa[p][i]!=fa[q][i]){ p=fa[p][i]; q=fa[q][i]; } } return fa[p][0]; } void modify(int u, int v, int val){ int lca=LCA(u,v); while(u!=lca){ w[edgenum[u]]=max(w[edgenum[u]],val); u=fa[u][0]; } while(v!=lca){ w[edgenum[v]]=max(w[edgenum[v]],val); v=fa[v][0]; } } int que(int u, int v){ int mi=1000001; int lca=LCA(u,v); while(u!=lca){ mi=min(mi,w[edgenum[u]]); u=fa[u][0]; } while(v!=lca){ mi=min(mi,w[edgenum[v]]); v=fa[v][0]; } return mi; } int main(){ memset(head,-1,sizeof(head)); scanf("%d", &n); for(int i=1;i<=n-1;++i){ int u,v; scanf("%d %d", &u, &v); add(u,v,i); add(v,u,i); } scanf("%d", &m); vector<vector<int>> query(m+1,vector<int>(3,0)); for(int i=1;i<=m;++i){ scanf("%d %d %d", &query[i][0], &query[i][1], &query[i][2]); } lg[1]=0; lg[2]=1; for(int i=3;i<=n;++i){ if(i==(1<<(lg[i-1]+1))){ lg[i]=lg[i-1]+1; }else{ lg[i]=lg[i-1]; } } dfs(1,0); for(int i=1;i<=m;++i){ int u=query[i][0]; int v=query[i][1]; int val=query[i][2]; modify(u,v,val); } for(int i=1;i<=m;++i){ int u=query[i][0]; int v=query[i][1]; int val=query[i][2]; int q=que(u,v); if(q!=val){ printf("-1"); return 0; } } for(int i=1;i<=n-1;++i){ if(w[i]==0) w[i]=1; printf("%d ", w[i]); } return 0; }