边双+LCA
code
#include<bits/stdc++.h>
namespace my_std
{
using namespace std;
#define rep(i,a,b) for (int i=(a);i<=(b);i++)
#define drep(i,a,b) for (int i=(a);i>=(b);i--)
#define go(u) for (int i=head[(u)];i;i=e[i].nxt)
#define pf printf
#define writeln(x) write(x),putchar('
')
#define writesp(x) write(x),putchar(' ')
#define mem(x,v) memset(x,v,sizeof(x))
typedef long long ll;
const int INF=0x7fffffff;
inline int read()
{
int sum=0,f=1;
char c=0;
while (!isdigit(c))
{
if (c=='-') f=-1;
c=getchar();
}
while (isdigit(c))
{
sum=(sum<<1)+(sum<<3)+(c^48);
c=getchar();
}
return sum*f;
}
void write(int k)
{
if (k<0) putchar('-'),k=-k;
if (k>=10) write(k/10);
putchar(k%10+'0');
}
}
using namespace my_std;
const int N=100010;
const int M=500010;
int n,m,quiz;
int cnt1,cnt2=1,head[N],HEAD[N];
int idx,low[N],dfn[N];
int col,color[N],sum[N],val[N];
int sum_plus[N];
int dep[N],f[N][21];
bool bridge[M<<1];
struct edge
{
int to,nxt;
}e[M<<1],E[M<<1];
void add1(int u,int v)
{
e[++cnt1].to=v;
e[cnt1].nxt=head[u];
head[u]=cnt1;
}
void add2(int u,int v)
{
E[++cnt2].to=v;
E[cnt2].nxt=HEAD[u];
HEAD[u]=cnt2;
}
void tarjan(int u,int last)
{
low[u]=dfn[u]=++idx;
for (int i=HEAD[u];i;i=E[i].nxt)
{
int v=E[i].to;
if (!dfn[v])
{
tarjan(v,i);
low[u]=min(low[u],low[v]);
if (low[v]>dfn[u])
{
bridge[i]=1;
bridge[i^1]=1;
}
}
else if (i!=(last^1)) low[u]=min(low[u],dfn[v]);
}
}
void get_color(int u,int r)
{
color[u]=r;
sum[color[u]]+=val[u];
for (int i=HEAD[u];i;i=E[i].nxt)
{
int v=E[i].to;
if (!color[v]&&!bridge[i])
{
get_color(v,r);
}
}
}
void build_tree()
{
rep(u,1,n)
{
for (int i=HEAD[u];i;i=E[i].nxt)
{
int v=E[i].to;
if (bridge[i])
{
add1(color[u],color[v]);
}
}
}
}
void dfs(int u,int fa)
{
dep[u]=dep[fa]+1;
f[u][0]=fa;
for (int i=1;(1<<i)<=dep[u];i++)
{
f[u][i]=f[f[u][i-1]][i-1];
}
go(u)
{
int v=e[i].to;
if (v==fa) continue;
dfs(v,u);
}
}
int lca(int x,int y)
{
if (dep[x]<dep[y]) swap(x,y);
drep(i,20,0)
{
if (dep[f[x][i]]>=dep[y]) x=f[x][i];
if (x==y) return x;
}
drep(i,20,0)
{
if (f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
void getsum(int u,int fa)
{
sum_plus[u]=sum_plus[fa]+sum[u];
go(u)
{
int v=e[i].to;
if (v==fa) continue;
getsum(v,u);
}
}
int solve(int u,int v)
{
if (color[u]==color[v]) return sum[color[u]];
int LCA=lca(color[u],color[v]);
int ans=sum_plus[color[u]]+sum_plus[color[v]]-sum_plus[LCA]-sum_plus[f[LCA][0]];
return ans;
}
int main()
{
n=read(),m=read();quiz=read();
rep(i,1,n) val[i]=read();
int u,v;
rep(i,1,m)
{
u=read(),v=read();
add2(u,v),add2(v,u);
}
tarjan(1,-INF);
rep(i,1,n) if (!color[i]) get_color(i,++col);
build_tree();
dfs(color[1],0);
getsum(color[1],0);
rep(i,1,quiz)
{
u=read(),v=read();
writeln(solve(u,v));
}
}
进阶版:BZOJ 2959