hdu 2874 Connections between cities hdu 2586 How far away ? LCA

两道lca模板题,用的是倍增法,nlogn预处理,logn查询。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define maxn  10100
struct Edge
{
    int u,v,w,next;
}e[100100];
int n,m,c;
int head[maxn],cnt;
int fa[maxn],cost[maxn],L[maxn];
int anc[maxn][20];
int parent[maxn];

int find(int x)
{
    if(parent[x]==x) return x;
    else return parent[x]=find(parent[x]);
}

void add(int u,int v,int w)
{
    e[cnt].u=u;
    e[cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
void dfs(int u,int father,int level)
{
    int i;
    L[u]=level;
    for(i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].v;
        if(v!=father)
        {
            fa[v]=u;
            cost[v]=cost[u]+e[i].w;
            dfs(v,u,level+1);
        }
    }
}
void pre()
{
    int i,j;
    for(i=0;i<n;i++)
    {
        anc[i][0]=fa[i];
        for(j=1;(1<<j)<n;j++) anc[i][j]=-1;
    }
    for(j=1;(1<<j)<n;j++)
        for(i=0;i<n;i++)
        {
            if(anc[i][j-1]!=-1)
            {
                int a=anc[i][j-1];
                anc[i][j]=anc[a][j-1];
            }
        }
}
int query(int p,int q)
{
    int tmp,log,i;
    if(L[p]<L[q]) swap(p, q);
    for(log=1;(1<<log)<=L[p];log++);log--;
    int ans=-1000000000;
    for(i=log;i>=0;i--)
        if(L[p]-(1<<i)>=L[q])
            p=anc[p][i];
    if(p==q) return p;
    for(i=log;i>=0;i--)
    {
        if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i])
        {
            p=anc[p][i];
            q=anc[q][i];
        }
    }
    return fa[p];
}
int main()
{
    int i,j;
    while(scanf("%d%d%d",&n,&m,&c)!=EOF)
    {
        memset(head,-1,sizeof(head));
        cnt=0;
        int x,y,z;
        for(i=1;i<=n;i++) parent[i]=i;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
            int px=find(x);
            int py=find(y);
            if(px!=py) parent[px]=py;
        }
        for(i=1;i<=n;i++)
            if(parent[i]==i)
            {
                add(0,i,0);
                add(i,0,0);
            }
        n++;
        cost[0]=0;
        dfs(0,-1,0);
        pre();
        for(i=1;i<=c;i++)
        {
            scanf("%d%d",&x,&y);
            if(find(x)!=find(y)) printf("Not connected\n");
            else
            {
                int xx=query(x,y);
                printf("%d\n",cost[x]+cost[y]-2*cost[xx]);
            }
        }
    }
    return 0;
}
#pragma comment(linker, "/STACK:1000000000,1000000000")
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define maxn  40100
struct Edge
{
    int u,v,w,next;
}e[100100];
int n,m;
int head[maxn],cnt;
int fa[maxn],cost[maxn],L[maxn];
int anc[maxn][20];

void add(int u,int v,int w)
{
    e[cnt].u=u;
    e[cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
void dfs(int u,int father,int level)
{
    int i;
    L[u]=level;
    for(i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].v;
        if(v!=father)
        {
            fa[v]=u;
            cost[v]=cost[u]+e[i].w;
            dfs(v,u,level+1);
        }
    }
}
void pre()
{
    int i,j;
    for(i=0;i<n;i++)
    {
        anc[i][0]=fa[i];
        for(j=1;(1<<j)<n;j++) anc[i][j]=-1;
    }
    for(j=1;(1<<j)<n;j++)
        for(i=0;i<n;i++)
        {
            if(anc[i][j-1]!=-1)
            {
                int a=anc[i][j-1];
                anc[i][j]=anc[a][j-1];
            }
        }
}
int query(int p,int q)
{
    int tmp,log,i;
    if(L[p]<L[q]) swap(p, q);
    for(log=1;(1<<log)<=L[p];log++);log--;
    int ans=-1000000000;
    for(i=log;i>=0;i--)
        if(L[p]-(1<<i)>=L[q])
            p=anc[p][i];
    if(p==q) return p;
    for(i=log;i>=0;i--)
    {
        if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i])
        {
            p=anc[p][i];
            q=anc[q][i];
        }
    }
    return fa[p];
}
int main()
{
    int cas,i,j;
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%d%d",&n,&m);
        memset(head,-1,sizeof(head));
        cnt=0;
        int x,y,z;
        for(i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            x--;
            y--;
            add(x,y,z);
            add(y,x,z);
        }
        dfs(0,-1,0);
        pre();
        cost[0]=0;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            x--;y--;
            int xx=query(x,y);
            printf("%d\n",cost[x]+cost[y]-2*cost[xx]);
        }
    }
    return 0;
}
时间: 2024-11-03 01:38:31

hdu 2874 Connections between cities hdu 2586 How far away ? LCA的相关文章

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 2874 Connections between cities (离线LCA)

题目地址:HDU 2874 好坑的一道题..MLE了好长时间....全用了前向星而且把G++改成了C++才过了.. LCA裸题,没什么好说的.. 代码如下; #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #in

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 2874 Connections between cities(LCA离线算法实现)

http://acm.hdu.edu.cn/showproblem.php?pid=2874 题意: 求两个城市之间的距离. 思路: LCA题,注意原图可能不连通. 如果不了解离线算法的话,可以看我之前博客写的解释http://www.cnblogs.com/zyb993963526/p/7295894.html 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cs

HDU - 2874 Connections between cities (LCA)

After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads h

Hdu 2874 Connections between cities

题意: 城市 道路  没有环 不一定连通的树 求两城市的最短距离 设想一下就是很多小树  那好办 思路: lca离线算法 然后有个技巧就是 每次我们tarjan一棵树不是最后树的节点都访问过并且孩子全能找到根嘛 那么我们只要做做做做 做到全部的城市都访问过了  就行了 反正你做这颗小树的时候又不会影响到其他树的 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; i

HDU - 2874 Connections between cities(LCA)

题目大意:给出N个点,M条线,Q个询问,询问的是两点之间的最短距离 解题思路:恶心的数据量,一不小心就超空间了 这题给图不是张连通图,是森林,所以计算两点之间的最短距离时还要考虑一下是否在同一棵树中 剩下的就是裸LCA了 #include <cstdio> #include <cstring> #define N 10010 #define M 20010 #define C 2000010 struct Edge{ int to, next, dis; }E[M]; struct

HDU 2874 Connections between cities(LCA离线)

 题意:一个森林,询问两个节点距离,若无法到达,输出Not connected. 思路:还是求LCA的思想,只需再对每个询问的两个节点判断是否在一棵树内即可. 有一个问题是这道题的query很大,达到了1000000,所以离线算法空间上比较虚, 然而只会离线的.....于是把int改成short int险过.... #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #