wikioi3287 货车运输

来源:互联网 发布:国服lol mac版 编辑:程序博客网 时间:2024/04/27 15:16
先是最大生成树建图,然后用最原始的LCA即可。
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define rep(i,n) for(int i=1;i<=n;++i)#define imax(x,y) (x>y?x:y)#define imin(x,y) (x<y?x:y)using namespace std;const int N=10010,M=60010,E=20010,BIG=1000000000;int firste[N],nexte[E],v[E],w[E];int fa[N],ceng[N],len[N];struct edge{    int u,v,w;}a[M];int n,m,q,e=0;bool cmp(edge xx,edge yy){    return xx.w>yy.w;}void build_edge(int x,int y,int z){    ++e;    nexte[e]=firste[x];    v[e]=y;    w[e]=z;    firste[x]=e;    ++e;    nexte[e]=firste[y];    v[e]=x;    w[e]=z;    firste[y]=e;}void dfs(int u){    int p=firste[u];    while(p)    {        if(!ceng[v[p]])        {            fa[v[p]]=u;            ceng[v[p]]=ceng[u]+1;            len[v[p]]=w[p];            dfs(v[p]);        }        p=nexte[p];    }}int findf(int x){    if(fa[x]==x)return x;    fa[x]=findf(fa[x]);    return fa[x];}int main(){        int x,y;    scanf("%d%d",&n,&m);    rep(i,m)    scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);    sort(a+1,a+1+m,cmp);    for(int i=1;i<n;++i)    {        a[m+i].u=1;        a[m+i].v=i+1;        a[m+i].w=0;    }    rep(i,n)fa[i]=i;    int k=1;    for(int i=1;i<n;++i)    {        while(findf(a[k].u)==findf(a[k].v))            ++k;        int tx=findf(a[k].u);        int ty=findf(a[k].v);        fa[tx]=ty;        build_edge(a[k].u,a[k].v,a[k].w);    }    rep(i,n)fa[i]=i;    ceng[1]=1;    dfs(1);    scanf("%d",&q);    rep(i,q)    {        scanf("%d%d",&x,&y);        int tx=ceng[x],ty=ceng[y],ans=BIG;        while(tx>ty)        {            ans=imin(ans,len[x]);            x=fa[x];            --tx;        }        while(ty>tx)        {            ans=imin(ans,len[y]);            y=fa[y];            --ty;        }        while(x!=y)        {            ans=imin(ans,len[x]);            ans=imin(ans,len[y]);            x=fa[x];            y=fa[y];        }        if(ans)printf("%d\n",ans);        else printf("-1\n");    }    return 0;}

0 0