zoukankan      html  css  js  c++  java
  • [2019 CSP-S赛前集训] [洛谷P1967] 货车运输

    题目链接:https://www.luogu.org/problem/P1967

    题目意思大概是要求路径的最小权值的最大值,我们可以将权值小的无关紧要的边去掉;

    方法可以使用最大生成树重新建图,然后再最大生成树上用LCA来回答每一个询问.

    这里博主使用倍增求LCA的,当时太菜了,没想到用倍增直接来存权值,就通过每个点的fa数组来求到LCA路径上的最小权值;

      1 #include <bits/stdc++.h>
      2 #define N 100000+5
      3 #define M 500000+5
      4 using namespace std;
      5 struct node
      6 {
      7     int u,v,wei;
      8 }a[M];
      9 int n,m,lgn,q;
     10 int ans;
     11 int f[N][25],fa[N],vis[N],depth[N],fw[N];
     12 vector <int> edge[N],w[N],wn[N];
     13 bool cmp(node a,node b)
     14 {
     15     return a.wei>b.wei;
     16 }
     17 int Find(int u)
     18 {
     19     while(u!=fa[u])
     20     {
     21         fa[u]=fa[fa[u]];
     22         u=fa[u];
     23     }
     24     return u;
     25 }
     26 void Kruskal()//求最大生成树
     27 {
     28     for(int i=1;i<=m;i++)
     29     {
     30         int u=a[i].u,v=a[i].v,wei=a[i].wei;
     31         int fau=Find(u),fav=Find(v);
     32         if(fau!=fav)
     33         {
     34             fa[fau]=fav;
     35             edge[u].push_back(v);
     36             w[u].push_back(wei);
     37             edge[v].push_back(u);
     38             w[v].push_back(wei);
     39         }
     40     }
     41 }
     42 void dfs(int u)
     43 {
     44     vis[u]=1;
     45     for(int i=0;i<edge[u].size();i++)
     46     {
     47         int now=edge[u][i];
     48         if(!vis[now])
     49         {
     50             f[now][0]=u;
     51             depth[now]=depth[u]+1;
     52             fw[now]=w[u][i];
     53             dfs(now);
     54         }
     55     }
     56 }
     57 void getfather()//倍增
     58 {
     59     for(int j=1;j<=lgn;j++)
     60     {    
     61         for(int i=1;i<=n;i++)
     62         {
     63             f[i][j]=f[f[i][j-1]][j-1];
     64         }
     65     }
     66 }
     67 int LCA(int u,int v)//LCA模板
     68 {
     69     if(depth[u]<depth[v]) swap(u,v);
     70     int dist=depth[u]-depth[v];
     71     int j=0;
     72     while(dist)
     73     {
     74         if(dist&1) u=f[u][j];
     75         dist>>=1;
     76         j++;
     77     }
     78     if(u==v) return u;
     79     for(int j=lgn-1;j>=0;j--)
     80     {
     81         if(f[u][j]!=f[v][j])
     82         {
     83             u=f[u][j];
     84             v=f[v][j];
     85         }
     86     }
     87     return f[u][0];
     88 }
     89 void work(int u,int com)//求到LCA路径上的最小权值
     90 {
     91     while(u!=com)
     92     {
     93         int nxt=f[u][0];
     94         ans=min(ans,fw[u]);
     95         u=nxt;
     96     }
     97 }
     98 int main()
     99 {
    100     scanf("%d%d",&n,&m);
    101     lgn=log2(n);
    102     for(int i=1;i<=m;i++)
    103     {
    104         scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].wei);
    105     }
    106     for(int i=1;i<=n;i++) fa[i]=i;
    107     sort(a+1,a+m+1,cmp);
    108     Kruskal();
    109     for(int i=1;i<=n;i++)
    110     {
    111         if(!vis[i]) dfs(i);
    112     }
    113     getfather();
    114     scanf("%d",&q);
    115     for(int i=1;i<=q;i++)
    116     {
    117         ans=INT_MAX;
    118         int u,v;
    119         scanf("%d%d",&u,&v);
    120         int lca=LCA(u,v);
    121         work(u,lca);
    122         work(v,lca);
    123         if(lca==0)printf("-1
    ");
    124         else printf("%d
    ",ans);
    125     }
    126     return 0;
    127 }
    转载请注明出处--Xx_queue
  • 相关阅读:
    ICE框架之Slice2CSharp映射---接口的映射
    ICE框架之Sclice2CSharp映射---结构的映射
    ICE框架之Sclice2CSharp映射---异常的处理
    ICE框架之Slice2CSharp映射---标识符、模块、内置类型的映射
    关于clientHeight、offsetHeight、scrollHeight[转]
    GridView中设置日期格式不起作用的解决方法
    提供 ice分布式程序设计中文版
    更换网卡后给网卡分配IP不成功的解决方法
    ICE框架之Slice2CSharp映射---字典的映射
    ICE框架之Slice2CSharp映射---异常的映射
  • 原文地址:https://www.cnblogs.com/Xx-queue/p/11701092.html
Copyright © 2011-2022 走看看