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