zoukankan      html  css  js  c++  java
  • JZOJ 5914. 盟主的忧虑

    Description

        江湖由 N 个门派(2≤N≤100,000,编号从 1 到 N)组成,这些门派之间有 N-1 条小道将他们连接起来,每条道路都以“尺”为单位去计量,武林盟主发现任何两个门派都能够直接或者间接通过小道连接。
        虽然整个江湖是可以互相到达的,但是他担心有心怀不轨之徒破坏这个武林的安定,破坏小道,于是武林盟主又秘密地修建了 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 的密道

    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
     
    做法:将所有密道按照权值从小到大排序。 对于一条密道(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 }
    View Code
  • 相关阅读:
    BGP community和联邦实验
    BGP RR的设计原则
    BGP不可比较的AS间的度量问题的解决办法
    BGP理解错误的部署RR造成的环路
    BGP数据结构表
    BGP RR的环路避免机制
    BGP Lab RR & Loop (1)
    Lab BGP Summary
    70、对象复用的了解,零拷贝的了解
    66、malloc、realloc、calloc的区别
  • 原文地址:https://www.cnblogs.com/traveller-ly/p/9818508.html
Copyright © 2011-2022 走看看