HDU 2586

时间:2023-03-08 17:49:16
HDU 2586

http://acm.hdu.edu.cn/showproblem.php?pid=2586

题意:求最近祖先节点的权值和

思路:LCA Tarjan算法

 #include <stdio.h>
#include <string.h>
#define maxn 40005 int m,n,x[maxn],y[maxn],z[maxn],head[maxn*],pos,dist[maxn],f[maxn];
bool vis[maxn];
struct Edge{
int to,val,next;
}edge[maxn*]; void add(int u,int v,int val)
{
edge[pos].to = v;
edge[pos].val = val;
edge[pos].next = head[u];
head[u] = pos++;
} int Find(int x)
{
if(f[x]!=x)
return f[x] =Find(f[x]);
return f[x];
} void Tarjan(int u)
{
vis[u] = true;
f[u] = u;
for(int i = ;i<=n;i++)
{
if(x[i]==u&&vis[y[i]]) z[i] = Find(y[i]);
if(y[i]==u&&vis[x[i]]) z[i] = Find(x[i]);
}
for(int i =head[u];i!=-;i=edge[i].next)
{
int v = edge[i].to;
if(!vis[v])
{
dist[v] =dist[u]+edge[i].val;
Tarjan(v);
f[v] = u;
}
}
} int main()
{
int t,a,b,c;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&m,&n);
memset(head,-,sizeof(head));
memset(vis,false,sizeof(vis)); pos = ;
for(int i = ;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
z[i] = ;
}
z[m] = ;
for(int i = ; i<=n;i++)
{
scanf("%d%d",&x[i],&y[i]); //分别存每一次的查询点。
}
dist[] = ;
Tarjan();
for(int i = ;i<=n;i++)
printf("%d\n",dist[x[i]]+dist[y[i]]-*dist[z[i]]);
}
return ;
}