zoukankan      html  css  js  c++  java
  • HDU 2874 /// tarjan离线求森林里两点的距离

    题目大意:

    在一个森林里 询问 u v 两点

    若不能到达输出 "Not connected" 否则输出两点距离

    https://blog.csdn.net/keyboarderqq/article/details/56842607

    和求树上两点差不多

    改变的是树上两点的vis标记改成了记录根节点

    此时 继续搜时 判断vis未标记过 就改成了是否存在根节点

    而 更新答案时 判断vis标记过 则改成了根节点是否与当前根节点相同

    #include <bits/stdc++.h>
    #define mem(i,j) memset(i,j,sizeof(i))
    using namespace std;
    
    const int N=1e4+5, Q=1e6+5;
    struct EDGE {
        int to, w, nt;
    }e[N<<1], q[Q<<1];
    int head[N], tot, que[N], pos;
    ///和HDU2586一样的毒 询问开N 如果开Q会MLE
    int fa[N], dis[N], root[N];
    int n, m, t, ans[Q];
    
    void init() {
        tot=1; mem(head,0);
        pos=1; mem(que,0);
        mem(root,0); mem(ans,-1);
    }
    void addE(int u,int v,int w) {
        e[tot].to=v, e[tot].w=w;
        e[tot].nt=head[u];
        head[u]=tot++;
    }
    void addQ(int u,int v,int w) {
        q[pos].to=v, q[pos].w=w;
        q[pos].nt=que[u];
        que[u]=pos++;
    }
    int getfa(int u) {
        if(fa[u]==u) return u;
        return fa[u]=getfa(fa[u]);
    }
    void Tarjan(int u,int rt) {
        fa[u]=u; root[u]=rt;
        for(int i=head[u];i;i=e[i].nt) {
            int v=e[i].to;
            if(!root[v]) {
                dis[v]=dis[u]+e[i].w;
                Tarjan(v,rt); fa[v]=u;
            }
        }
        for(int i=que[u];i;i=q[i].nt) {
            int v=q[i].to;
            if(root[v]==rt)
                ans[q[i].w]=dis[u]+dis[v]-2*dis[getfa(v)];
        }
    }
    int main()
    {
        while(~scanf("%d%d%d",&n,&m,&t)) {
            init();
    
            for(int i=0;i<m;i++) {
                int u,v,w; scanf("%d%d%d",&u,&v,&w);
                addE(u,v,w); addE(v,u,w);
            }
            for(int i=1;i<=t;i++) {
                int u,v; scanf("%d%d",&u,&v);
                addQ(u,v,i), addQ(v,u,i);
            }
    
            for(int i=1;i<=n;i++)
                if(!root[i]) {
                    dis[i]=0;
                    Tarjan(i,i);
                }
    
            for(int i=1;i<=t;i++)
                 if(ans[i]==-1) puts("Not connected");
                 else printf("%d
    ",ans[i]);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    php header 跳转 ie问题
    Filter过滤不了Action的问题
    DB2中sql语句占位符问题
    LL(1)文法
    算法分析实验报告词法分析器
    大数据概述
    2016.9.30 编译原理词法分析器
    131有确定性的有穷自动机
    Python基础综合练习
    组合数据类型练习
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10020740.html
Copyright © 2011-2022 走看看