zoukankan      html  css  js  c++  java
  • [洛谷P1967][题解]货车运输

    题目

    这道题让我们求最小限重的最大值

    显然可以先求出最大生成树,然后在树上进行操作

    因为如果两点之间有多条路径的话一定会走最大的,而其他小的路径是不会被走的

    然后考虑求最小权值

    可以采用倍增求LCA,预处理时顺便把最小权值求出来

    Code:

      1 #include<bits/stdc++.h>
      2 #define IO4 10000+10
      3 #define debug cout<<"Error"<<endl
      4 using namespace std;
      5 int n,m,q,cnt,cntt;
      6 //原图 
      7 struct Edge {
      8     int from,to,wei;
      9 }e[10*IO4];
     10 inline void ade(int u,int v,int w){
     11     e[++cnt].from=u;
     12     e[cnt].to=v;
     13     e[cnt].wei=w;
     14 }
     15 inline bool cmp(Edge a,Edge b){
     16     return a.wei>b.wei;
     17 }
     18 //最大生成树 
     19 struct Edget {
     20     int nextt,tot,weit;
     21 }te[2*IO4];
     22 int head[IO4];
     23 inline void adte(int u,int v,int w){
     24     te[++cntt].tot=v;
     25     te[cntt].weit=w;
     26     te[cntt].nextt=head[u];
     27     head[u]=cntt;
     28 }
     29 //并查集 
     30 int fa[IO4];
     31 int fd(int x){
     32     return fa[x]==x?x:fa[x]=fd(fa[x]);
     33 }
     34 //Kruskal算法 
     35 inline void Solve_MST(){
     36     int now=0;
     37     sort(e+1,e+1+cnt,cmp);
     38     for(int i=1;i<=n;i++)fa[i]=i;
     39     for(int i=1;i<=cnt;i++){
     40         int u=fd(e[i].from);
     41         int v=fd(e[i].to);
     42         if(u==v)continue;
     43         fa[u]=v;
     44         //建新图 
     45         adte(u,v,e[i].wei);
     46         adte(v,u,e[i].wei);
     47         now++;
     48         if(now==n-1)return;
     49     }
     50 }
     51 //搜索 
     52 int f[IO4][25],minw[IO4][25],vis[IO4],dep[IO4];
     53 void DFS(int x){
     54     vis[x]=1;
     55     for(int i=head[x];i;i=te[i].nextt){
     56         int tot=te[i].tot;
     57         if(vis[tot])continue;
     58         dep[tot]=dep[x]+1;
     59         f[tot][0]=x;
     60         //两个直接连接的点之间的最小权值就是这条边 
     61         minw[tot][0]=te[i].weit;
     62         DFS(tot);
     63     }
     64 }
     65 //预处理 
     66 inline void Init(){
     67     for(int i=1;i<=n;i++){
     68         if(!vis[i]){
     69             DFS(i);
     70             f[i][0]=i;
     71             minw[i][0]=0x3f3f3f3f;
     72         }
     73     }
     74     for(int l=1;l<=20;l++){
     75         for(int i=1;i<=n;i++){
     76             f[i][l]=f[f[i][l-1]][l-1];
     77             //这里多了一步求最小权值
     78             //minw=min(前半minw,后半minw) 
     79             minw[i][l]=min(minw[i][l-1],minw[f[i][l-1]][l-1]);
     80         }
     81     }
     82 }
     83 //倍增求LCA(以下都是常规操作) 
     84 inline int Solve_LCA(int x,int y){
     85     int ans=0x3f3f3f3f;
     86     if(fd(x)!=fd(y))return -1;
     87     if(dep[x]<dep[y])swap(x,y);
     88     for(int l=20;l>=0;l--){
     89         if(dep[x]-(1<<l)>=dep[y]){
     90             //注意要先取min否则x会改变 
     91             ans=min(ans,minw[x][l]);
     92             x=f[x][l];
     93         }
     94     }
     95     if(x==y)return ans;
     96     for(int l=20;l>=0;l--){
     97         if(f[x][l]!=f[y][l]){
     98             //同上 
     99             ans=min(ans,min(minw[x][l],minw[y][l]));
    100             x=f[x][l],y=f[y][l];
    101         }
    102     }
    103     //由于跳到LCA下面所以再取一步 
    104     ans=min(ans,min(minw[x][0],minw[y][0]));
    105     return ans;
    106 }
    107 
    108 int main(){
    109     ios::sync_with_stdio(0);
    110     cin>>n>>m;
    111     for(int i=1;i<=m;i++){
    112         int x,y,z;
    113         cin>>x>>y>>z;
    114         ade(x,y,z);
    115     }
    116     Solve_MST();
    117     Init();
    118     cin>>q;
    119     for(int i=1;i<=q;i++){
    120         int x,y;
    121         cin>>x>>y;
    122         cout<<Solve_LCA(x,y)<<endl;
    123     }
    124     return 0;//完结撒花 
    125 }
    内容来自_ajhfff_的博客(https://www.cnblogs.com/juruoajh/),未经允许,不得转载。
  • 相关阅读:
    501. 二叉搜索树中的众数
    530. 二叉搜索树的最小绝对差
    Java强制类型转换注意
    PL_SQL常用快捷键及设置
    Java线程:大总结
    Java多线程售票程序分析
    Java多线程的几种实现方式
    Java线程的几种状态
    Java的同步机制:synchronized关键字
    Eclipse常用设置[不断完善]
  • 原文地址:https://www.cnblogs.com/juruoajh/p/12080245.html
Copyright © 2011-2022 走看看