您的位置:首页 > 产品设计 > UI/UE

poj 1986 Distance Queries(LCA:倍增/离线)

2013-08-15 09:31 197 查看
计算树上的路径长度。input要去查poj 1984。

任意建一棵树,利用树形结构,将问题转化为u,v,lca(u,v)三个点到根的距离。输出d[u]+d[v]-2*d[lca(u,v)]。

倍增求解:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define clr(a,m) memset(a,m,sizeof(a))
using namespace std;

const int MAXN=44444;

struct Edge{
int v,next,c;
Edge(){}
Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
}edge[MAXN<<1];

struct EDGE{
int u,v;
int ans;
EDGE(){}
EDGE(int _u,int _v):u(_u),v(_v),ans(-1){}
};

int head[MAXN],tol;
int p[MAXN],vis[MAXN],dis[MAXN];

queue<int>q;
vector<int>query[MAXN];
vector<EDGE>G;

void init()
{
tol=0;
clr(head,-1);
}

void add(int u,int v,int c)
{
edge[tol]=Edge(v,c,head[u]);
head[u]=tol++;
}

void build(int m)
{
init();
rep(i,1,m){
int u,v,c;
scanf("%d%d%d%*s",&u,&v,&c);
add(u,v,c);
add(v,u,c);
}

int k;
scanf("%d",&k);
rep(i,1,k){
int u,v,siz;
scanf("%d%d",&u,&v);

G.push_back(EDGE(u,v));
siz=G.size();
query[u].push_back(siz-1);

G.push_back(EDGE(v,u));
siz=G.size();
query[v].push_back(siz-1);
}
}

void bfs(int x)
{
clr(vis,0);
clr(dis,0);
while(!q.empty())
q.pop();
q.push(x);
vis[x]=1;
dis[x]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(vis[v])
continue;
q.push(v);
vis[v]=1;
dis[v]=dis[u]+edge[i].c;
}
}
}

int find(int x)
{
return (x==p[x])?x:(p[x]=find(p[x]));
}

void dfs(int x)
{
vis[x]=1;
for(int i=head[x];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(vis[v])
continue;
dfs(v);
p[v]=x;
}

int siz =query[x].size()-1;
rep(i,0,siz)
{
int t=query[x][i];
if(vis[G[t].v]){
G[t].ans=find(G[t].v);
}
}
}

void LCA(int rt,int n)
{
clr(vis,0);
rep(i,1,n)
p[i]=i;
dfs(rt);
}

void PRT()
{
int siz=G.size();
for(int i=0;i<siz;i+=2)
{
int u=G[i].u;
int v=G[i].v;
if(G[i].ans!=-1)
printf("%d\n",dis[u]+dis[v]-2*dis[G[i].ans]);
else
printf("%d\n",dis[u]+dis[v]-2*dis[G[i^1].ans]);
}
}

int main()
{
int n,m;
scanf("%d%d",&n,&m);
build(m);
bfs(1);
LCA(1,n);
PRT();
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: