换了个姿势还是上了HDU 据学长给我的图论题库来说 lca问题也写完了
这题几乎还是模板题 只不过是多了个 判断是否在同一棵树上 用了点小技巧 再Tarjan时 把根节点也传上去 如果得结果时根节点不同就跳过
另外这题灰常容易爆内存 稍微改了一下用 C++水过去了 然而G++还是爆………………
AC Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int maxn=10005;
const int inf=0x3f3f3f3f;
struct node
{
int v,d;
node* nxt;
};
node *head1[maxn],edge1[maxn*2];
node *head2[maxn],edge2[2000002];
int root[maxn],ans[1000002],dis[maxn];
int vis[maxn];
int n,lnum,qnum,idx1,idx2;
void init()
{
for(int i=0;i<=n;i++)
{
head1[i]=head2[i]=0;
vis[i]=0;
}
idx1=idx2=0;
}
int fin(int x)
{
if(root[x]==x) return x;
return root[x]=fin(root[x]);
}
void add(int u,int v,int d,node *head[],node edge[],int& idx)
{
edge[idx].v=v;
edge[idx].d=d;
edge[idx].nxt=head[u];
head[u]=edge+idx++;
edge[idx].v=u;
edge[idx].d=d;
edge[idx].nxt=head[v];
head[v]=edge+idx++;
}
void Tarjan(int u,int rot)
{
root[u]=u;
vis[u]=rot;
for(node* p=head2[u];p;p=p->nxt)
if(vis[p->v]==rot)
ans[p->d]=dis[u]+dis[p->v]-2*dis[fin(p->v)];
for(node* p=head1[u];p;p=p->nxt)
if(!vis[p->v])
{
dis[p->v]=dis[u]+p->d;
Tarjan(p->v,rot);
root[p->v]=u;
}
}
int main()
{
int u,v,d;
while(scanf("%d%d%d",&n,&lnum,&qnum)!=EOF)
{
init();
for(int i=1;i<=lnum;i++)
{
scanf("%d %d %d",&u,&v,&d);
add(u,v,d,head1,edge1,idx1);
}
for(int i=1;i<=qnum;i++)
{
scanf("%d %d",&u,&v);
ans[i]=inf;
add(u,v,i,head2,edge2,idx2);
}
for(int i=1;i<=n;i++)
if(!vis[i])
{
dis[i]=0;
Tarjan(i,i);
}
for(int i=1;i<=qnum;i++)
{
if(ans[i]==inf) puts("Not connected");
else printf("%d\n",ans[i]);
}
}
return 0;
}