ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

$Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$

2019-10-03 15:01:46  阅读:271  来源: 互联网

标签:Noip2013 int 货车运输 ret read Luogu1967 Rg find define


$Luogu$

 

$Sol$

首先当然是构建一棵最大生成树,然后对于一辆货车的起点和终点倍增跑$lca$更新答案就好.记得预处理倍增的时候不仅要处理走了$2^i$步后是那个点,还有这中间经过的路径权值的最小值以便之后统计答案.

再一看发现这题并没说给的图是联通的,也就是说跑了最大生成树之后可能有若干棵树.所以构树的时候要注意不能随便选一个点构完就不管了,要对每一个联通块都构一次.其他的地方似乎没有因为它有多棵树而有什么不同,只是询问的时候看下是不是一个联通块里的就好.

 

$Code$

 

#include<bits/stdc++.h>
#define il inline
#define Rg register
#define go(i,a,b) for(Rg int i=a;i<=b;++i)
#define yes(i,a,b) for(Rg int i=a;i>=b;--i)
#define e(i,u) for(Rg int i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Rg int x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=10010;
int n,m,q,f[N],b[N],ct,c[N][11],d[N][11],dep[N];
bool vis[N];
struct node{int u,v,w;}eg[N*5];
struct node1{int v,w,nt;}a[N*10];
il bool cmp(node x,node y){return x.w>y.w;}
il int find(int x){if(x==f[x])return x;return f[x]=find(f[x]);}
il void add(int u,int v,int w){a[++ct]=(node1){v,w,b[u]};b[u]=ct;}
il void dfs(int u)
{
    vis[u]=1;
    e(i,u)
    {
        Rg int v=a[i].v,w=a[i].w;
        if(vis[v])continue;
        dep[v]=dep[u]+1;c[v][0]=u;d[v][0]=w;
        go(j,1,10)c[v][j]=c[c[v][j-1]][j-1],d[v][j]=min(d[v][j-1],d[c[v][j-1]][j-1]);
        dfs(v);
    }
}
il int sol(int u,int v)
{
    Rg int ret=inf;
    if(dep[u]<dep[v])swap(u,v);
    yes(j,10,0)
    {
        if(dep[c[u][j]]>dep[v])ret=min(ret,d[u][j]),u=c[u][j];
    }
    if(dep[u]>dep[v])ret=min(ret,d[u][0]),u=c[u][0];
    if(u==v)return ret;
    yes(j,10,0)if(c[u][j]!=c[v][j])ret=min(ret,min(d[u][j],d[v][j])),u=c[u][j],v=c[v][j];
    ret=min(ret,min(d[u][0],d[v][0]));
    return ret;
}
int main()
{
    n=read(),m=read();
    go(i,1,n)f[i]=i;
    go(i,1,m)eg[i]=(node){read(),read(),read()};
    sort(eg+1,eg+m+1,cmp);
    go(i,1,m)
    {
        Rg int u=eg[i].u,v=eg[i].v,w=eg[i].w;
        if(find(u)==find(v))continue;
        f[find(u)]=find(v);
        add(u,v,w),add(v,u,w);
    }
    go(i,1,n)if(!vis[i])dep[i]=1,dfs(i);
    q=read();
    while(q--)
    {
        Rg int u=read(),v=read();
        if(find(u)!=find(v))printf("-1\n");
        else printf("%d\n",sol(u,v));//cout<<endl;
    }
    return 0;
}
View Code

 

 

 

标签:Noip2013,int,货车运输,ret,read,Luogu1967,Rg,find,define
来源: https://www.cnblogs.com/forward777/p/11416175.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有