NOIP 2013 提高组 洛谷P1967 货车运输 (Kruskal重构树)

Posted ynhnxn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP 2013 提高组 洛谷P1967 货车运输 (Kruskal重构树)相关的知识,希望对你有一定的参考价值。

题目:

A 国有 nn 座城市,编号从 11 到 nn,城市之间有 mm 条双向道路。每一条道路对车辆都有重量限制,简称限重。

现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

 

 

对于每一组询问,相当于求点x到点y中所有路径中最小边权的最大值,这样就是货车的最大载重。

那么这显然可以用Kruskal重构树来解决,将重构树建成大根堆,就可以求最大边权的最小值;同理,小根堆就是最小边权的最大值。

那么做这道题就是重构树的模板题了。复杂度O(q logn)。

 #include<bits/stdc++.h>
 using namespace std;
 const int N=2e5+10;
 struct edge
     int u,v,w;
     bool operator < (const edge &x)
         return w>x.w;    //小根堆 
     
 e[N];
 vector<int> g[N];
 int n,m,q,cnt,fa[N],vis[N],val[N],d[N],f[N][30];
 int find(int x)
     return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
 
 
 void kruskal()
     sort(e+1,e+m+1);
     for(int i=1;i<=n;i++) fa[i]=i;
     for(int i=1;i<=m;i++)
         int fu=find(e[i].u),fv=find(e[i].v);
         if(fu!=fv)
             val[++cnt]=e[i].w;
             fa[cnt]=fa[fu]=fa[fv]=cnt;
             g[cnt].push_back(fu);
             g[cnt].push_back(fv);
             g[fu].push_back(cnt);
             g[fv].push_back(cnt);
         
     
 
 
 void dfs(int u,int fa)
     d[u]=d[fa]+1,f[u][0]=fa,vis[u]=1;
     for(int i=1;(1<<i)<=d[u];i++)
         f[u][i]=f[f[u][i-1]][i-1];
     for(int i=0;i<g[u].size();i++)
         int v=g[u][i];
         if(v!=fa) dfs(v,u);
     
 
 
 int lca(int x,int y)
     if(d[x]<d[y]) swap(x,y);
     for(int i=25;i>=0;i--)
         if(d[f[x][i]]>=d[y]) x=f[x][i];
     if(x==y) return x;
     for(int i=25;i>=0;i--)
         if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
     return f[x][0];
 
 
 int main()
     scanf("%d%d",&n,&m);
     cnt=n;
     for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
     kruskal();
     for(int i=1;i<=cnt;i++)//注意图可能是个森林,不要漏掉 
         if(!vis[i])
             int f=find(i);
             dfs(f,0);
         
     
     scanf("%d",&q);
     while(q--)
         int u,v;
         scanf("%d%d",&u,&v);
         if(find(u)!=find(v)) cout<<-1<<endl;
         else cout<<val[lca(u,v)]<<endl;
     
     return 0;
 

 

以上是关于NOIP 2013 提高组 洛谷P1967 货车运输 (Kruskal重构树)的主要内容,如果未能解决你的问题,请参考以下文章

[NOIP2013提高组]货车运输

P1967 [NOIP2013 提高组] 货车运输

[luogu P1967][NOIp2013]P1967 货车运输

3287 货车运输 2013年NOIP全国联赛提高组 40 分

洛谷 P1967 货车运输 题解

洛谷P1967货车运输