zoukankan      html  css  js  c++  java
  • COGS 2075. [ZLXOI2015][异次元圣战III]ZLX的陨落

    ★★☆   输入文件:ThefallingofZLX.in   输出文件:ThefallingofZLX.out   简单对比
    时间限制:1 s   内存限制:256 MB

    【题目描述】

    正当革命如火如荼,情侣教会日薄西山之时,SOX和FFF的分歧却越来越大,SOX认为情侣教会不合适的、无限制的秀恩爱和阶级歧视值得反对,而FFF认为一切情侣都该从这个世界上消失。

    SOX先发制人,率先接管了全国政权并突袭了FFF,暗杀了FFF的首领,FFF的红色革命事业遭到了空前的打击,一些FFF团员积极抵抗,另一些FFF团员隐居避世,而一些FFF团员则走向极端,参加了一个邪恶组织:诅咒教会

    你虽然对SOX下山摘桃子的行为不满,但你对邪教更不满。在对诅咒教会的长期调查中,你发现该组织的操纵者是亡灵巫师ZLX!现在,维护正义的使命降到了你身上!你和其他的一些远征军将士前往ZLX的城堡,却掉入了ZLX的魔法陷阱--扭曲虚空,扭曲虚空由n个魔法结界空间组成,m条虚空隧道连接着它们,你和其他的远征军将士(恰好有n个)分散在魔法结界空间里,只有会合在一起,你们才能冲破封锁(扭曲虚空是一颗树)。现在,你向平行世界的你提出了疑问,如果给出两个人会合,总共至少需要多少魔法能量?

    已知虚空隧道的长度与消耗的魔法能量在数值上相等。

    ZLX的末日已经到临,等到你冲出虚空隧道,亲手结果了ZLX吧!

    【输入格式】

    第一行一个正整数N,代表魔法结界空间的个数,一个正整数M,代表虚空隧道的个数

    接下来M行,每行三个数u,v,w,代表虚空隧道连接的两个点和虚空隧道的长度

    接下来一个正整数Q,代表查询个数

    接下来Q行,每行两个数u,v代表询问从uv需要消耗的魔法能量

    【输出格式】

    Q行,每行一个正整数

    【样例输入】

    6 5

    1 2 7

    1 3 3

    2 4 5

    3 5 7

    4 6 6

    5

    3 4

    6 3

    5 1

    4 3

    4 2

    【样例输出】

    15

    21

    10

    15

    5

    【提示】

    对于20%的数据,n<=300,q<=300

    对于40%的数据,n<=2000,q<=2000

    对于100%的数据,n<=100000,q<=100000,w<=32767m=n1

     

    果lca求两点距离

    屠龙宝刀点击就送

    tarjan法rank1 

    #include <cstdio>
    #include <vector>
    #include <cctype>
    #define N 100005
    inline void read(int &x)
    {
        register char ch=getchar();
        for(x=0;!isdigit(ch);ch=getchar());
        for(;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    }
    using namespace std;
    vector<int>vec[N];
    int n,m,q,y,cnt,to[N<<1],head[N<<1],nextt[N<<1],u[N],v[N],dad[N],fa[N],ans[N],val[N],DIS[N<<1];
    int find_(int x) {return x==fa[x]?x:fa[x]=find_(fa[x]);}
    void Dfs(int x)
    {
        fa[x]=x;
        for(register int i=head[x];i;i=nextt[i])
        {
            int v=to[i];
            if(v==dad[x]) continue;
            dad[v]=x;
            val[v]=DIS[i]+val[x];
            Dfs(v);
        }
        for(register int i=0;i<vec[x].size();++i) if(dad[y=x^u[vec[x][i]]^v[vec[x][i]]]) ans[vec[x][i]]=find_(y);
        fa[x]=dad[x];
    }
    int Main()
    {
        freopen("ThefallingofZLX.in","r",stdin);
        freopen("ThefallingofZLX.out","w",stdout);
        read(n); read(m);
        for(int U,V,W;m--;)
        {
            read(U); read(V); read(W);
            nextt[++cnt]=head[U];to[cnt]=V;DIS[cnt]=W;head[U]=cnt;
            nextt[++cnt]=head[V];to[cnt]=U;DIS[cnt]=W;head[V]=cnt;
        }
        read(q);
        for(register int i=1;i<=q;++i)
        {
            read(u[i]); read(v[i]);
            vec[u[i]].push_back(i);
            vec[v[i]].push_back(i);  
        }
        Dfs(1);
        for(register int i=1;i<=q;++i) printf("%d
    ",val[u[i]]+val[v[i]]-2*val[ans[i]]);
        return 0;
    }
    int sb=Main();
    int main(int argc,char *argv[]) {;}
    View Code

    倍增

    #include <cstdio>
    #define N 100005
    int n,m,q,cnt,to[N<<1],head[N<<1],nextt[N<<1],dep[N],dad[N][25],val[N],DIS[N<<1];
    void Dfs(int x)
    {
        dep[x]=dep[dad[x][0]]+1;
        for(int i=0;dad[x][i];++i) dad[x][i+1]=dad[dad[x][i]][i];
        for(int i=head[x];i;i=nextt[i])
        {
            int v=to[i];
            if(v==dad[x][0]) continue;
            dad[v][0]=x;
            val[v]=DIS[i]+val[x];
            Dfs(v);
        }
    }
    inline void swap(int &m,int &n)
    {
        int tmp=n;
        n=m;
        m=tmp;
    }
    inline int lca(int x,int y)
    {
        if(dep[x]>dep[y]) swap(x,y);
        for(int i=20;i>=0;--i)
        if(dep[dad[y][i]]>=dep[x])
        y=dad[y][i];
        if(x==y) return x;
        for(int i=20;i>=0;--i)
        if(dad[y][i]!=dad[x][i])
        y=dad[y][i],x=dad[x][i];
        return dad[x][0];
    }
    int main(int argc,char *argv[])
    {
        freopen("ThefallingofZLX.in","r",stdin);
        freopen("ThefallingofZLX.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int u,v,w;m--;)
        {
            scanf("%d%d%d",&u,&v,&w);
            nextt[++cnt]=head[u];to[cnt]=v;DIS[cnt]=w;head[u]=cnt;
            nextt[++cnt]=head[v];to[cnt]=u;DIS[cnt]=w;head[v]=cnt;
        }
        Dfs(1);
        scanf("%d",&q);
        for(int u,v;q--;)
        {
            scanf("%d%d",&u,&v);
            int Lca=lca(u,v);
            printf("%d
    ",val[u]+val[v]-2*val[Lca]);
        }
        return 0;
    }
  • 相关阅读:
    一天一个 Linux 命令(44):ifstat 命令
    Java集合框架示意图
    Java中String类常见问题汇总
    一天一个 Linux 命令(43):netstat 命令
    Windows系统下,如何设置maven字符编码
    Java文件操作编程
    Java 注解(Annotation)
    Linux Centos7.4 更新Java jdk版本
    Java基础(6)Java数据类型扩展
    Windows系统下Elasticsearch7.15.2单服务器配置多节点
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7738683.html
Copyright © 2011-2022 走看看