http://acm.hdu.edu.cn/showproblem.php?pid=2874
LCA Tarjan算法
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N=10010,M=20010;
struct edge
{
int v,w,next;
}e[M];
int em;
int head[N],n;
struct qes
{
int v,k;
};
vector<qes> q[N];
int dis[N],vis[N],set[N],anc[N],col[N],cc;
int ans[1000010];
void insert(int u,int v,int w)
{
edge et={v,w,head[u]};
e[em]=et;
head[u]=em++;
}
void graphinit()
{
em=0;
memset(head,-1,sizeof(head));
}
void qesinit()
{
cc=0;
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(col,0,sizeof(col));
for(int i=1;i<=n;i++) q[i].clear();
}
int find(int x)
{
return x==set[x]?x:set[x]=find(set[x]);
}
void merge(int u,int v)
{
set[find(v)]=find(u);
}
void LCA(int u,int d)
{
set[u]=u;
vis[u]=1;
dis[u]=d;
anc[find(u)]=u;
for(int i=head[u];i!=-1;i=e[i].next) if(!vis[e[i].v])
{
int v=e[i].v;
LCA(v,d+e[i].w);
merge(u,v);
anc[find(u)]=u;
}
col[u]=cc;
int sz=q[u].size();
for(int i=0;i<sz;i++)
{
int v=q[u][i].v, k=q[u][i].k;
if(col[v]==cc) ans[k]=dis[u]+dis[v]-2*dis[anc[find(v)]];
else ans[k]=-1;
}
}
int main()
{
int m,c;
while(~scanf("%d%d%d",&n,&m,&c))
{
graphinit();
while(m--)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w);
insert(v,u,w);
}
qesinit();
for(int i=0;i<c;i++)
{
int u,v;
scanf("%d%d",&u,&v);
qes t1={v,i};
q[u].push_back(t1);
qes t2={u,i};
q[v].push_back(t2);
}
for(int i=1;i<=n;i++)
if(!vis[i]) {cc++; LCA(i,0);}
for(int i=0;i<c;i++)
if(ans[i]!=-1) printf("%d\n",ans[i]);
else printf("Not connected\n");
}
return 0;
}