HDU 2586 How far away ?(LCA Tarjan/树上倍增)

HDU2586

题目:问任意两个点之间的最短路径长。

如果用Tarjan做的话,那么

用LCA算出最近公共祖先lca,长度就是dis[u]+dis[v]-2*dis[lca]

#include
#include
#include
#include
#include
#include
#define eps 1e-8
#define memset(a,v) memset(a,v,sizeof(a))
using namespace std;
typedef long long int LL;
const int MAXL(4*1e4);
const int INF(0x7f7f7f7f);
const int mod(1e9+7);
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
struct node
{
    int to;
    int next,w;
} edge[2*MAXL+50];
int head[2*MAXL+50];
int father[MAXL+50];
int ans[MAXL+50];
int dis[MAXL+50];
bool vis[MAXL+50];
int x[MAXL+50],y[MAXL+50];
struct nodee
{
    int ed,id;
} nod;
vectorv[MAXL+50];
int cnt;

int Find(int x)
{
    if(x!=father[x])
        father[x]=Find(father[x]);
    return father[x];
}

void Join(int x,int y)
{
    int fx=Find(x),fy=Find(y);
    if(fx!=fy)
        father[fy]=fx;
}


void LCA(int u)
{
    vis[u]=true;
    for(int i=head[u]; ~i; i=edge[i].next)
    {
        int v=edge[i].to,w=edge[i].w;
        if(!vis[v])
        {
            dis[v]=dis[u]+w;
            LCA(v);
            Join(u,v);
        }
    }
    for(int i=0; i

 

树上倍增

#include
#include
#include
#include
#include
#include
#define eps 1e-8
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define memset(a,v) memset(a,v,sizeof(a))
using namespace std;
typedef long long int LL;
const int MAXL(4*1e4);
const int INF(0x7f7f7f7f);
const int mod(1e9+7);
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
struct node{
    int to,next,w;
    node(){}
    node(int to,int next,int w):to(to),next(next),w(w){}
}edge[2*MAXL+50];
int head[2*MAXL+50];
int depth[MAXL+50];
int dp[MAXL+50][20];
int dis[MAXL+50][20];
bool vis[MAXL+50];
int n,q,cnt;

void init(){
    cnt=0;
    memset(head,-1);
    memset(dp,0);
    memset(depth,0);
    memset(dis,0);
    memset(vis,false);
}

void add_edge(int x,int y,int z){
    edge[cnt]=node(y,head[x],z);
    head[x]=cnt++;
}

void getDepth(int u){
    vis[u]=true;
    for(int i=head[u];~i;i=edge[i].next){
        int to=edge[i].to,w=edge[i].w;
        if(!vis[to]){
            depth[to]=depth[u]+1;
            dis[to][0]=w;
            dp[to][0]=u;
            getDepth(to);
        }
    }
}

void getDp(){
    for(int up=1;(1<=0;j--)
        if(depth[x]-(1<=depth[y])
            ans+=dis[x][j],x=dp[x][j];
    if(x==y) return ans;
    for(int j=i;j>=0;j--){
        if(dp[x][j]!=dp[y][j]){
            ans+=dis[x][j];
            ans+=dis[y][j];
            x=dp[x][j];
            y=dp[y][j];
        }
    }
    return ans+dis[x][0]+dis[y][0];
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%d%d",&n,&q);
        for(int i=1;i

 

你可能感兴趣的:(数据结构,图论)