HDU 2784 Connections between cities 并查集+Online_LCA

模板攒起来
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>

#pragma comment(linker, "/STACK:1024000000");
#define LL long long int

using namespace std;

const int MAXN = 10010;
const int MAXM = 10010;

struct N
{
    int v,w,next;
}edge[MAXM*2];
int Top;
int head[MAXN];
int MAXSIZE;
int dep[MAXN];
int seq[MAXN*2];
int R[MAXN];

struct ST
{
    int dep,point;
    bool operator < (const ST &A) const
    {
        return dep < A.dep;
    }
}st[MAXN*8];

void Link(int u,int v,int w)
{
    edge[Top].v = v;
    edge[Top].w = w;
    edge[Top].next = head[u];
    head[u] = Top++;
}

void Init()
{
    memset(head,-1,sizeof(head));
    Top = 0;
    MAXSIZE = 0;
}

void InitDep(int s,int pre = -1,int d = 0)
{
    R[s] = ++MAXSIZE;
    seq[MAXSIZE] = s;
    dep[s] = d;

    for(int p =  head[s]; p != -1; p = edge[p].next)
    {
        if(edge[p].v != pre)
        {
            InitDep(edge[p].v,s,d+edge[p].w);
            seq[++MAXSIZE] = s;
        }
    }
}

void InitST(int site,int l,int r)
{
    if(l == r)
    {
        st[site].dep = dep[seq[l]];
        st[site].point = seq[l];
        return ;
    }

    int mid = (l+r)>>1;

    InitST(site<<1,l,mid);
    InitST(site<<1|1,mid+1,r);

    st[site] = st[site<<1].dep < st[site<<1|1].dep ? st[site<<1] : st[site<<1|1];
}

ST QueryLCA(int site,int L,int R,int l,int r)
{
    if(L == l && R == r)
        return st[site];

    int mid = (L+R)>>1;

    if(r <= mid)
        return QueryLCA(site<<1,L,mid,l,r);
    else if(mid < l)
        return QueryLCA(site<<1|1,mid+1,R,l,r);

    return min(QueryLCA(site<<1,L,mid,l,mid),QueryLCA(site<<1|1,mid+1,R,mid+1,r));

}

int fa[MAXN];

int Find(int x)
{
    int t = x,f;
    while(t != fa[t])
        t = fa[t];
    while(x != fa[x])
        f = fa[x],fa[x] = t,x = f;
    return x;
}

int main()
{
    int n,m,c;
    int u,v,w;
    int i,l,r;
    ST LCA;

    while(scanf("%d %d %d",&n,&m,&c) != EOF)
    {
        Init();

        for(i = 1;i <=  n; ++i)
            fa[i] = i;

        while(m--)
        {
            scanf("%d %d %d",&u,&v,&w);
            Link(u,v,w);
            Link(v,u,w);
            fa[Find(u)] = Find(v);
        }

        for(i = 1;i <= n; ++i)
            if(fa[i] == i) Link(0,i,0),Link(i,0,0);

        InitDep(0);
        InitST(1,1,MAXSIZE);

        while(c--)
        {
            scanf("%d %d",&u,&v);

            if(Find(u) != Find(v))
            {
                puts("Not connected");
                continue;
            }

            l = min(R[u],R[v]);
            r = max(R[u],R[v]);

            LCA = QueryLCA(1,1,MAXSIZE,l,r);

            printf("%d\n",dep[u]+dep[v]-dep[LCA.point]*2);
        }
    }
    return 0;
}

时间: 2024-11-02 15:47:16

HDU 2784 Connections between cities 并查集+Online_LCA的相关文章

HDU 3371 Connect the Cities(并查集+Kruskal)

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=3371 思路: 这道题很明显是一道最小生成树的题目,有点意思的是,它事先已经让几个点联通了.正是因为它先联通了几个点,所以为了判断连通性 很容易想到用并查集+kruskal. 不过要注意 这题有一个坑点,就是边数很多 上限是25000,排序的话可能就超时了.而点数则比较少 上限是500,所以很多人选择用Prim做.但我个人觉得这样连通性不好判断.其实边数多没关系,我们主要去重就好啦,用邻接矩阵存下两点

hdu 2874 Connections between cities(lca-&gt;rmq)

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4425    Accepted Submission(s): 1263 Problem Description After World War X, a lot of cities have been seriously damag

HDU 3635 延缓更新的并查集

Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2839    Accepted Submission(s): 1097 Problem Description Five hundred years later, the number of dragon balls will increase unexpecte

HDU 3461 Code Lock(并查集的应用+快速幂)

* 65536kb,只能开到1.76*10^7大小的数组.而题目的N取到了10^7,我开始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 其实路径压缩也可以不用.............  题目的大意: 一个密码锁上有编号为1到N的N个字母,每个字母可以取26个小写英文字母中的一个.再给你M个区间[L,M],表示该区间的字母可以一起同步"增加"(从'a'变为'b'为增1,'z'增1为'a').假如一组密码按照给定的区间进行有限

HDU 1558 Segment set (并查集+线段非规范相交)

题目链接 题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出. 思路 : 先判断与其他线段是否相交,然后合并. 1 //1558 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <cmath> 6 #define eps 1e-8 7 #define zero(x) (((x) > 0 ? (x) : (-x)) < e

HDU——2874 Connections between cities

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11927    Accepted Submission(s): 2775 Problem Description After World War X, a lot of cities have been seriously dama

hdu 2874 Connections between cities 带权lca判是否联通

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some mat

hdu 3635 Dragon Balls(并查集应用)

Problem Description Five hundred years later, the number of dragon balls will increase unexpectedly, so it's too difficult for Monkey King(WuKong) to gather all of the dragon balls together. His country has N cities and there are exactly N dragon bal

HDU 3407.Zjnu Stadium 加权并查集

Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3726    Accepted Submission(s): 1415 Problem Description In 12th Zhejiang College Students Games 2007, there was a new stadium built