• 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;
    }
  • 相关阅读:
    luogu 1865 数论 线性素数筛法
    洛谷 2921 记忆化搜索 tarjan 基环外向树
    洛谷 1052 dp 状态压缩
    洛谷 1156 dp
    洛谷 1063 dp 区间dp
    洛谷 2409 dp 月赛题目
    洛谷1199 简单博弈 贪心
    洛谷1417 烹调方案 dp 贪心
    洛谷1387 二维dp 不是特别简略的题解 智商题
    2016 10 28考试 dp 乱搞 树状数组
  • 原文地址:https://www.cnblogs.com/ruojisun/p/7738683.html
Copyright © 2020-2023  润新知