Description
江湖由 N 个门派(2≤N≤100,000,编号从 1 到 N)组成,这些门派之间有 N-1 条小道将他们连接起来,每条道路都以“尺”为单位去计量,武林盟主发现任何两个门派都能够直接或者间接通过小道连接。
虽然整个江湖是可以互相到达的,但是他担心有心怀不轨之徒破坏这个武林的安定,破坏小道,于是武林盟主又秘密地修建了 M 条密道(1≤M≤100,000),但每条小道距离都不超过10亿尺。
果不其然,最近一个名叫“太吾”的组织意欲破坏武林的小道,请你帮盟主想想办法,如果门派 A 到门派 B 的直连小道被破坏,从 A 走到 B 的所有路径中,经过密道的距离最少是多少?
虽然整个江湖是可以互相到达的,但是他担心有心怀不轨之徒破坏这个武林的安定,破坏小道,于是武林盟主又秘密地修建了 M 条密道(1≤M≤100,000),但每条小道距离都不超过10亿尺。
果不其然,最近一个名叫“太吾”的组织意欲破坏武林的小道,请你帮盟主想想办法,如果门派 A 到门派 B 的直连小道被破坏,从 A 走到 B 的所有路径中,经过密道的距离最少是多少?
Input
第一行数字 N M
接下来 N-1 行,每行两个整数 A B,表示 A-B 间有一条直连小道
接下来 M 行,每行三个数字 A B V,表示 A-B 间有一条代价为 V 的密道
接下来 N-1 行,每行两个整数 A B,表示 A-B 间有一条直连小道
接下来 M 行,每行三个数字 A B V,表示 A-B 间有一条代价为 V 的密道
Output
输出 N-1 行,对应原输入的小道,每个小道被破坏后,最少需要经过多长的密道?如果不存在替换的道路,请输出-1
Sample Input
6 3 4 1 1 3 4 5 1 2 6 5 3 6 8 2 3 7 6 4 5
Sample Input
6 3 4 1 1 3 4 5 1 2 6 5 3 6 8 2 3 7 6 4 5
Data Constraint
30%数据:N<=300,M<=1000
50%数据:N<=1000,M<=1000
70%数据:N<=5000,M<=5000
对于另外15%的数据点:树是一条链
100%数据:N,M<=100,000
50%数据:N<=1000,M<=1000
70%数据:N<=5000,M<=5000
对于另外15%的数据点:树是一条链
100%数据:N,M<=100,000
做法:将所有密道按照权值从小到大排序。 对于一条密道(u,v,w),如果u到v的路径上的边中存在边之前还没有被覆盖过,那么说明这条边的答案就是w. 可以用并查集维护,维护每个集合深度最小的节点,对于密道(u,v,w),每次u都在它所在集合中找到深度最小的 点,这个点与父亲的连边一定就是上述的边,将这条边的答案更新为w,然后将这个节点与其父亲合并,直到u所 在集合的深度最小的节点是小于u和v的lca的,对v做同样的过程即可。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #define LL long long 6 #define N 100007 7 using namespace std; 8 struct edge{ 9 int x,to,next; 10 int w,id; 11 }e[2*N]; 12 struct arr{ 13 int x,y; 14 int w; 15 }a[2*N]; 16 int n,m,ls[N],tot,f[N],fa[N][2],dep[N],cnt; 17 int c[N],ans[N]; 18 19 void add(int x,int y,int id){ 20 e[++tot].to=y; 21 e[tot].x=x; 22 e[tot].id=id; 23 e[tot].next=ls[x]; 24 ls[x]=tot; 25 } 26 27 void Init(){ 28 scanf("%d%d",&n,&m); 29 for (int i=1;i<n;i++){ 30 int u,v; 31 scanf("%d%d",&u,&v); 32 add(u,v,i); 33 add(v,u,i); 34 } 35 for (int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w); 36 for (int i=1;i<=n;i++) f[i]=i; 37 } 38 39 int find(int x){ 40 if (f[x]==x) return x; 41 return f[x]=find(f[x]); 42 } 43 44 void Dfs(int x,int pre){ 45 fa[x][0]=pre; 46 dep[x]=dep[pre]+1; 47 for (int i=ls[x];i;i=e[i].next){ 48 int v=e[i].to; 49 if (v==pre) continue; 50 c[v]=e[i].id; 51 Dfs(v,x); 52 } 53 } 54 55 int cmp(arr x,arr y){ 56 return x.w<y.w; 57 } 58 void Work(){ 59 sort(a+1,a+m+1,cmp); 60 for (int i=1;i<=m;i++){ 61 int u=a[i].x,v=a[i].y; 62 int q=find(u); 63 int p=find(v); 64 while (q!=p){ 65 if (dep[q]<dep[p]) swap(q,p); 66 ans[c[q]]=a[i].w; 67 q=f[q]=find(fa[q][0]); 68 } 69 } 70 for (int i=1;i<n;i++) if (ans[i]!=0) printf("%d ",ans[i]); else printf("-1 "); 71 } 72 73 int main(){ 74 freopen("worry.in","r",stdin); 75 freopen("worry.out","w",stdout); 76 Init(); 77 Dfs(1,0); 78 Work(); 79 }