zoukankan      html  css  js  c++  java
  • bzoj 3732Network

    先搞个最小生成树,然后lca(和之前的一个cf题差不多2333, 纯属颓废了。。)

    顺便思考了一下正确性。

    因为所求的是所有路径中最大边的最小值。而kruskal每次往里添加的就是最小边。所以在生成树之后两点之间的路径,都是严格按最小的插入的,所以里面的最大边会最小。(貌似说了些废话,,,)

     1 #include<bits/stdc++.h>
     2 #define inf 0x7fffffff
     3 #define LL long long
     4 #define N 100005
     5 using namespace std;
     6 inline int ra()
     7 {
     8     int x=0,f=1; char ch=getchar();
     9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    11     return x*f;
    12 }
    13 struct node{
    14     int to,next,v;
    15 }e[N<<1];
    16 struct data{
    17     int x,y,v;
    18 }a[N];
    19 int n,m,k;
    20 int head[N],cnt,deep[N],father[N],f[N][20],mx[N][20]; 
    21 void insert(int x, int y, int v)
    22 {
    23     e[++cnt].to=y;
    24     e[cnt].next=head[x];
    25     e[cnt].v=v;
    26     head[x]=cnt;
    27 }
    28 int find(int x){return father[x]==x?x:father[x]=find(father[x]);}
    29 bool cmp(data a, data b){return a.v<b.v;}
    30 void dfs(int x, int fa)
    31 {
    32     for (int i=1; i<=18; i++)
    33     {
    34         f[x][i]=f[f[x][i-1]][i-1];
    35         mx[x][i]=max(mx[x][i-1],mx[f[x][i-1]][i-1]);
    36     }
    37     for (int i=head[x];i;i=e[i].next)
    38     {
    39         if (e[i].to==fa) continue;
    40         f[e[i].to][0]=x;
    41         mx[e[i].to][0]=e[i].v;
    42         deep[e[i].to]=deep[x]+1;
    43         dfs(e[i].to,x);
    44     }
    45 }
    46 int getans(int x, int y)
    47 {
    48     int ans=0;
    49     if (deep[x]<deep[y]) swap(x,y);
    50     int t=deep[x]-deep[y];
    51     for (int i=0; i<=18; i++) 
    52         if (t&(1<<i)) ans=max(ans,mx[x][i]),x=f[x][i];
    53     for (int i=18; i>=0; i--)
    54         if (f[x][i]!=f[y][i])
    55         {
    56             ans=max(ans,max(mx[x][i],mx[y][i]));
    57             x=f[x][i]; y=f[y][i];
    58         }
    59     if (x!=y) return max(ans,max(mx[x][0],mx[y][0]));
    60     return ans;
    61 }
    62 int main()
    63 {
    64     n=ra(); m=ra(); k=ra();
    65     for (int i=1; i<=m; i++)
    66         a[i].x=ra(),a[i].y=ra(),a[i].v=ra();
    67     sort(a+1,a+m+1,cmp);
    68     for (int i=1; i<=n; i++) father[i]=i;
    69     int tot=0;
    70     for (int i=1; i<=m; i++)
    71     {
    72         int p=find(a[i].x),q=find(a[i].y);
    73         if (q!=p)
    74             father[q]=p,tot++,insert(a[i].x,a[i].y,a[i].v),insert(a[i].y,a[i].x,a[i].v);
    75         if (tot==n-1) break;
    76     }
    77     dfs(1,0);
    78     for (int i=1; i<=k; i++)
    79     {
    80         int x=ra(),y=ra();
    81         printf("%d
    ",getans(x,y));
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    交互题
    线段树
    最小生成树
    拓扑排序
    欧拉回路
    RMQ问题
    dfs序与求子树子节点(染了色)的个数
    dp题
    树状数组与离散化
    没做完的题
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6385117.html
Copyright © 2011-2022 走看看