pku 1986 Distance Queries(LCA-tarjan算法)
//1375MS,超慢啊 :
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
#define MAXN 50005
#define MAXQ 10001
int N,father[MAXN],ance[MAXN],dis[MAXN],res[MAXQ];
struct ENode
{
int adv,dis;
};
struct QNode
{
int adv,idx;
};
vector<ENode> adjlist[MAXN];
vector<QNode> query[MAXN];
bool visited[MAXN],color[MAXN];
int find_mfs(int x)
{
int i,t;
for(i=x;father[i]>0;i=father[i]) ;
while(x!=i)
{
t=father[x];
father[x]=i;
x=t;
}
return i;
}
void merge_mfs(int x,int y)
{
int fx,fy;
fx=find_mfs(x);
fy=find_mfs(y);
if(fx==fy) return;
if(father[fx]>father[fy]) //-3>-4
{
father[fy]+=father[fx];
father[fx]=fy;
}
else
{
father[fx]+=father[fy];
father[fy]=fx;
}
}
void lca_tarjan(int u,int d)
{
// father[u]=-1;
ance[u]=u;
visited[u]=true;
dis[u]=d;
for(size_t j=0;j<adjlist[u].size();j++)
{
int v=adjlist[u][j].adv;
if(visited[v]) continue;
lca_tarjan(v,d+adjlist[u][j].dis);
merge_mfs(u,v);
ance[find_mfs(u)]=u;
}
color[u]=true;
for(size_t k=0;k<query[u].size();k++)
{
int w=query[u][k].adv;
if(color[w])
{
int x=ance[ find_mfs(w) ];
// printf("ance=%d\n",x);
res[query[u][k].idx]=dis[u]+dis[w]-2*dis[x];
}
}
}
int main()
{
int M,Q,i,j,k,d;
char ch;
ENode e;
QNode q;
while(scanf("%d %d",&N,&M)!=EOF)
{
getchar();
for(i=1;i<=N;i++)
{
father[i]=-1;
visited[i]=false;
color[i]=false;
adjlist[i].clear();
query[i].clear();
}
for(k=0;k<M;k++)
{
scanf("%d %d %d %c",&i,&j,&d,&ch);
e.adv=j;
e.dis=d;
adjlist[i].push_back(e);
e.adv=i;
adjlist[j].push_back(e);
getchar();
}
scanf("%d",&Q);
for(k=0;k<Q;k++)
{
scanf("%d %d",&i,&j);
q.adv=j;
q.idx=k;
query[i].push_back(q);
q.adv=i;
query[j].push_back(q);
}
lca_tarjan(1,0);
for(k=0;k<Q;k++) printf("%d\n",res[k]);
}
return 0;
}
浙公网安备 33010602011771号