zoukankan      html  css  js  c++  java
  • Tarjan缩点+LCA【洛谷P2416】 泡芙

    P2416 泡芙

    题目描述

    火星猫经过一番努力终于到达了冥王星。他发现冥王星有 N 座城市,M 条无向边。火星猫准备出发去找冥王兔,他听说有若干泡芙掉落在一些边上,他准备采集一些去送给冥王兔。但是火星猫的火星光环和冥王星相生相克,当火星猫走过一条路之后,这条路就不能再走了。如果冥王兔吃不到泡芙,他们就不能嘿嘿嘿了。所以告诉你火星猫和冥王兔的位置,请问冥王兔能不能吃到泡芙。

    输入输出格式

    输入格式:

    第一行 N,M 表示点数和边数。

    接下来 M 行每行 X,Y,Z 表示 X 到 Y 有一条无向边,Z=1 表示有泡芙,Z=0 表示没有

    接下来一行是 Q,表示有 Q 组询问。

    每行 S,T 表示火星猫和冥王兔的位置。

    输出格式:

    对于每组询问输出 YES 或 NO

    LCA一定要初始化倍增 pre。

    话说我不初始化还能得60分。

    code:

    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    const int wx=800017;
    
    inline int read(){
        int sum=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
        return sum*f;
    }
    
    int a[wx],belong[wx],dfn[wx],low[wx],size[wx];
    int head[wx],h[wx],st[wx],dep[wx],dis[wx];
    int f[wx][23];
    int n,m,q;
    int top,tot,num,Num,col;
    
    struct e{
        int nxt,to,dis;
    }edge[wx*2];
    
    struct ee{
        int nxt,to,dis;
    }e[wx*2];
    
    void Add(int from,int to,int dis){
        e[++Num].nxt=h[from];
        e[Num].to=to;
        e[Num].dis=dis;
        h[from]=Num;
    }
    
    void add(int from,int to,int dis){
        edge[++num].nxt=head[from];
        edge[num].to=to;
        edge[num].dis=dis;
        head[from]=num;
    }
    
    void Tarjan(int u,int fa){
        dfn[u]=low[u]=++tot;
        st[++top]=u;
        for(int i=h[u];i;i=e[i].nxt){
            int v=e[i].to;
            if(v==fa)continue;
            if(!dfn[v]) Tarjan(v,u), low[u]=min(low[u],low[v]);
            else if(!belong[v]) low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u]){
            belong[u]=++col;
            size[col]=1;
            while(st[top]!=u){
                belong[st[top]]=col;
                size[col]++;
                top--;
            }
            top--;
        }
    }
    
    void CQ(){
        for(int u=1;u<=n;u++){
            for(int i=h[u];i;i=e[i].nxt){
                int v=e[i].to;
                if(belong[u]!=belong[v])
                    add(belong[u],belong[v],e[i].dis);
                else a[belong[u]]+=e[i].dis;
            }
        }
    }
    
    void dfs(int u,int fa){
        dep[u]=dep[fa]+1;
        for(int i=head[u];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(v==fa)continue;
            f[v][0]=u; dis[v]=dis[u]+edge[i].dis+a[v];
            dfs(v,u);
        }
    }
    
    void pre(){
        for(int j=1;j<=20;j++)
            for(int i=1;i<=n;i++)
                f[i][j]=f[f[i][j-1]][j-1];
    }
    
    int LCA(int x,int y){
        if(dep[x]<dep[y])swap(x,y);
        for(int i=20;i>=0;i--)
            if(dep[f[x][i]]>=dep[y])x=f[x][i];
        if(x==y)return x;
        for(int i=20;i>=0;i--)
            if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    
    int main(){
        n=read(); m=read();
        for(int i=1;i<=m;i++){
            int x,y,z; 
            x=read(); y=read(); z=read();
            Add(x,y,z); Add(y,x,z);
        }
        for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i,0);
        CQ();
        dis[belong[1]]=a[belong[1]];
    	dfs(belong[1],0); pre();
        q=read();
        for(int i=1;i<=q;i++){
            int x,y;
            x=read(); y=read();
            x=belong[x]; y=belong[y];
            int lca=LCA(x,y);
            if(dis[x]+dis[y]-2*dis[lca]+a[lca]>0)puts("YES");
            else puts("NO");
        }
        return 0;
    }
    
  • 相关阅读:
    谈谈目前书店里面的计算机书籍“含量”情况 发发看法
    注意:CSS中加入中文注释,会使.NET中样式丢失
    今天很是郁闷
    用周末的时间,通过BT终于把VS2005Team版下载下来啦~~~
    今天在网上找到了两个常用建模工具的下载地址 ,速度还不错
    C#下如何实现服务器+客户端的聊天程序
    CSS网页制作技巧:图片的自适应居中和兼容处理(转)
    SASS用法指南(转)
    CSS选择器学习小结
    JavaScript编写计算器《JavaScript王者归来》读书笔记1
  • 原文地址:https://www.cnblogs.com/wangxiaodai/p/9822654.html
Copyright © 2011-2022 走看看