poj 1986tarjan模板题

#include<iostream>
#include<vector>
using namespace std;
const int N=40010;
int pre[N];//并查集
int visit[N];//是否经过
int ancestor[N];//祖先
int dis[N];//储存距离
int result[N];//储存结果
struct tre{
 int x,length;
};
vector<tre>tree[N];
struct  qu{
 int y,index;
};
vector<qu>qury[N];
void init(int n) {//初始化
 int i;
 for(i=1;i<=n;i++)
  tree[i].clear();
 for(i=1;i<=n;i++)
  qury[i].clear();
 memset(visit,0,sizeof(visit));
}
int find(int x) {//路径压缩
 if(x!=pre[x])
  pre[x]=find(pre[x]);
 return pre[x];
}
void infind(int x,int y) {//合并
 int f1=find(x);
 int f2=find(y);
    pre[f1]=f2;
 return ;
}
void tarjan(int u,int length) {
 visit[u]=1;
 dis[u]=length;//直接就可以的到距离
 ancestor[u]=u;
       pre[u]=u;
 int i;
 for(i=0;i<tree[u].size();i++) {
  int v=tree[u][i].x;
  if(visit[v]==0) {
   tarjan(v,length+tree[u][i].length);
   infind(u,v);
   ancestor[find(u)]=u;
  }
 }
  for(i=0;i<qury[u].size();i++) {
   int v=qury[u][i].y;
   if(visit[v])
    result[qury[u][i].index]=dis[u]+dis[v]-2*dis[ancestor[find(v)]];//重点
  }
  return ;
}
int main() {
 int n,m,i,j,k,a,b,c;
 char s[2];
 while(scanf("%d%d",&n,&m)!=EOF) {
  init(n);
  for(i=1;i<=m;i++) {
   scanf("%d%d%d%s",&a,&b,&c,s);
   tre h;
   h.x=b;
   h.length=c;
   tree[a].push_back(h);//储存
   h.x=a;
   h.length=c;
   tree[b].push_back(h);
  }
  scanf("%d",&k);
  for(i=1;i<=k;i++) {
   scanf("%d%d",&a,&b);
   qu h;
    h.y=b;
    h.index=i;
    qury[a].push_back(h);//储存
    h.y=a;
    h.index=i;
    qury[b].push_back(h);
  }
  tarjan(1,0);//
  for(i=1;i<=k;i++)
   printf("%d ",result[i]);
 }
 return 0;
}

原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410891.html