#include<cstdio>
#include<cstring>
#include<iostream>
const int maxn=90005;//数组要开大一点
using namespace std;
int head[maxn],head1[maxn],fa[maxn],ranks[maxn],dist[maxn],vis[maxn],n,m,from,to,longs,query;
int index,idx;
struct Edge{
int v;
int next;
int length;
}e[maxn];
Edge qe[maxn];
/*void init()
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
ranks[i]=0;
}
}*/
int found(int x)
{
return fa[x]==x?x:fa[x]=found(fa[x]);
}
/*void unions(int a,int b)
{
a=found(a);
b=found(b);
if(a==b)
return ;
if(ranks[a]>ranks[b])
fa[b]=a;
else{
fa[a]=b;
if(ranks[a]==ranks[b])
++ranks[b];
}
}*/
void addEdge(int a,int b,int l)
{
e[idx].length=l;
e[idx].v=b;
e[idx].next=head[a];
head[a]=idx++;
}
void add(int a,int b)
{
qe[index].v=b;
qe[index].next=head1[a];
head1[a]=index++;
}
void lcatarjan(int d)
{
vis[d]=1;
fa[d]=d;
for(int i=head[d];i!=-1;i=e[i].next)
{
if(!vis[e[i].v])
{
dist[e[i].v]=dist[d]+e[i].length;
lcatarjan(e[i].v);
fa[e[i].v]=d;
}
}
for(int i=head1[d];i!=-1;i=qe[i].next)
{
if(vis[qe[i].v])
{
qe[i].length=dist[d]+dist[qe[i].v]-2*dist[found(qe[i].v)];
qe[i^1].length=qe[i].length;///这里的意思是同一层树的距离相同(画图理解)
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
//init();
idx=0,index=0;
memset(head,-1,sizeof(head));
memset(head1,-1,sizeof(head1));
memset(vis,0,sizeof(vis));
memset(e,0,sizeof(e));
memset(qe,0,sizeof(qe));
memset(fa,0,sizeof(fa));
memset(dist,0,sizeof(dist));
for(int i=0;i<m;i++)
{
scanf("%d%d%d %*c",&from,&to,&longs);
addEdge(from,to,longs);
addEdge(to,from,longs);
}
scanf("%d",&query);
for(int j=0;j<query;j++)
{
scanf("%d%d",&from,&to);
add(from,to);
add(to,from);
}
lcatarjan(1);
//cout<<"i:"<<index<<endl;
for(int i=0;i<index;i=i+2)
printf("%d\n",qe[i].length);
}
return 0;
}
更多tarjan详解
点这里
poj1986 lca(tarjan算法)
最新推荐文章于 2020-12-26 10:40:53 发布