JZOJ1738. Heatwave

来源:互联网 发布:美化状态栏的软件 编辑:程序博客网 时间:2024/06/03 21:21

1738. Heatwave

题解

先做一遍最小生成树(Kruscal),再求每个询问中两点到他们的LCA的路径上边的最大值。

SRC

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define N 15000+10#define M 40000+10struct Etype{    int u,v,d;}E[M];const int MX=15;int Node[M],Next[M],D[M],Head[N],tot;int f[N];int Fa[N][20],V[N][20],H[N];int n,m,Q;bool cmp(Etype a,Etype b) {return a.d < b.d ;}void Swap(int *a,int *b) {int t=*a; *a=*b; *b=t;}void link(int u,int v,int w) {    Node[++tot]=v;    D[tot]=w;    Next[tot]=Head[u];    Head[u]=tot;}int getfather(int x) {    if(f[x]==x) return x;    return f[x]=getfather(f[x]);}void DFS(int F,int x,int depth) {    H[x]=depth;    for(int p=Head[x];p;p=Next[p]) {        if(Node[p]==F) continue;        Fa[Node[p]][0]=x;        V[Node[p]][0]=D[p];        DFS(x,Node[p],depth+1);    }}int Lca(int x,int y) {    int ans=0;    if(H[x]<H[y]) swap(x,y);    for(int i=MX;i>=0;i--)         if(H[Fa[x][i]]>=H[y]) {            ans=max(ans,V[x][i]);            x=Fa[x][i];        }    if(x==y) return ans;    for(int i=MX;i>=0;i--) {        if(Fa[x][i]!=Fa[y][i]) {            ans=max(ans,V[x][i]);            ans=max(ans,V[y][i]);            x=Fa[x][i];            y=Fa[y][i];        }    }    ans=max(ans,V[x][0]);    ans=max(ans,V[y][0]);    return ans;}int main(){    scanf("%d%d%d",&n,&m,&Q);    for(int i=1;i<=n;i++) f[i]=i;    for(int i=1;i<=m;i++) {        scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].d);    }    sort(E+1,E+m+1,cmp);    for(int i=1;i<=m;i++) {        int f1=getfather(E[i].u);        int f2=getfather(E[i].v);        if(f1!=f2) {            f[f2]=f1;            link(E[i].u,E[i].v,E[i].d);            link(E[i].v,E[i].u,E[i].d);        }    }    DFS(0,1,1);    for(int k=1;k<=MX;k++) {        for(int i=1;i<=n;i++) {            if(!Fa[Fa[i][k-1]][k-1]) continue;            Fa[i][k]=Fa[Fa[i][k-1]][k-1];            V[i][k]=max(V[i][k-1],V[Fa[i][k-1]][k-1]);        }    }    for(int i=1;i<=Q;i++) {        int u,v;        scanf("%d%d",&u,&v);        printf("%d\n",Lca(u,v));    }    return 0;}
1 0
原创粉丝点击