这道题一次RE 。。查询的数组 开小了= =
一次MLE Vector开大了。。无力吐槽
这题很巧妙在于建立一个虚拟根节点 0,它到所有点的距离都为0,如果两个点的LCA为0,就说明这2个点不相连。
LCA这篇博客讲得很好http://dongxicheng.org/structure/lca-rmq/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<string>
#define inf 0x7fffffff
#define maxn 10010
#define maxq 1000010
using namespace std;
typedef struct node
{
int v,w;
}N;
int n,m,k;
vector<N> v1[maxn],v2[maxn];
int vis[maxn];
int color[maxn];
int ans[maxq];
int dis[maxn];
int fa[maxn];
int anc[maxn];
void init()
{
int i;
for(i=0;i<=n;i++)
{
v1[i].clear();
v2[i].clear();
fa[i]=i;
}
memset(vis,0,sizeof(vis));
memset(color,0,sizeof(color));
memset(ans,-1,sizeof(ans));
memset(dis,0,sizeof(dis));
memset(anc,-1,sizeof(anc));
}
int find(int x)
{
if(fa[x]!=x)
fa[x]=find(fa[x]);
return fa[x];
}
void merge(int x,int y)
{
fa[find(x)]=find(y);
}
void tarjan(int u)
{
int i;
vis[u]=1;
anc[u]=u;
for(i=0;i<v1[u].size();i++)
{
int v=v1[u][i].v;
if(vis[v]==0)
{
dis[v]=dis[u]+v1[u][i].w;
tarjan(v);
merge(v,u);
anc[find(u)]=u;
}
}
color[u]=1;
for(i=0;i<v2[u].size();i++)
{
int vv=v2[u][i].v;
if(color[vv]==1&&find(vv)!=0)
{
int w=v2[u][i].w;
ans[w]=dis[u]+dis[vv]-2*dis[anc[find(vv)]];
}
}
return ;
}
int main() {
freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&k)==3)
{
init();
int i;
for(i=1;i<=n;i++)
{
N nod;
nod.v=i;
nod.w=0;
v1[0].push_back(nod);
nod.v=0;
nod.w=0;
v1[i].push_back(nod);
}
int a,b,c;
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
N nod;
nod.v=b;
nod.w=c;
v1[a].push_back(nod);
nod.v=a;
nod.w=c;
v1[b].push_back(nod);
}
for(i=0;i<k;i++)
{
scanf("%d%d",&a,&b);
N nod;
nod.v=b;
nod.w=i;
v2[a].push_back(nod);
nod.v=a;
nod.w=i;
v2[b].push_back(nod);
}
tarjan(0);
for(i=0;i<k;i++)
{
if(ans[i]==-1)
printf("Not connected\n");
else
printf("%d\n",ans[i]);
}
}
return 0;
}