Title
Solution
- 注意会有重边,求 d i s dis dis的时候注意要取最小值
- 此题数据较大,需要快读和快输,不然会 T L E TLE TLE
Code
#include
#define rr register
#define ll long long
#define rep(i,x,y) for(register ll i=x;i<=y;i++)
using namespace std;
const ll N=200011;
const ll M=500011;
ll ext;
ll ans;
ll n,m,R=1,Q;
ll seg[N],rev[M],size[N],son[N],top[N],dep[N],TOT;
ll father[N],tot;
ll first[M],next[M],go[M],dis[N],d[M];
inline ll mymin(ll x,ll y){
return x<y?x:y;
}
inline void myswap(ll &x,ll &y){
ll t; t=x; x=y; y=t; return;
}
inline void in_add(rr ll x,rr ll y,rr ll z){
next[++tot]=first[x],first[x]=tot,go[tot]=y,d[tot]=z;
}
inline void insert(rr ll x,rr ll y,rr ll z){
in_add(x,y,z); in_add(y,x,z);
}
inline ll get(){
rr char c; rr ll sign=1;
while ((c=getchar())<'0'||c>'9') if (c=='-') sign=-1; rr ll res=c-'0';
while((c=getchar())>='0'&&c<='9') res=res*10+c-'0';
return res*sign;
}
inline void write(rr ll x){
if (x>9) write(x/10); putchar(x%10+48);
}
inline void dfs1(rr ll u,rr ll f){
rr ll e,v;
size[u]=1;
father[u]=f;
dep[u]=dep[f]+1;
for(e=first[u];v=go[e],e;e=next[e])
if (v!=f){
if (!dis[v]) dis[v]=dis[u]+d[e]; else dis[v]=mymin(dis[v],dis[u]+d[e]);
dfs1(v,u);
size[u]+=size[v];
if (size[v]>size[son[u]]) son[u]=v;
}
return;
}
inline void dfs2(ll u,ll linp){
rr ll e,v;
seg[u]=++seg[0],rev[seg[0]]=u,top[u]=linp;
if (!son[u]) return;
dfs2(son[u],linp);
for(e=first[u],v;v=go[e],e;e=next[e])
if (v!=father[u]&&v!=son[u]) dfs2(v,v);
return;
}
inline ll lca(rr ll x,rr ll y){
rr ll fx=top[x],fy=top[y];
while(fx!=fy){
if (dep[fx]<dep[fy]) myswap(x,y),myswap(fx,fy);
x=father[fx]; fx=top[x];
}
if (dep[x]>dep[y]) myswap(x,y);
return x;
}
ll dfn[N],low[N],cnt,b[N];
ll sum[N];
void square_point(ll u,ll v,ll w){
++ext;
ll pre=w,i=v,P;
while (i!=father[u])
sum[i]=pre,pre+=b[i],i=father[i];
sum[ext]=sum[u]; sum[u]=0; i=v;
while (i!=father[u])
P=mymin(sum[i],sum[ext]-sum[i]),insert(ext,i,P),i=father[i];
return;
}
struct node{
int y,z,next;
}A[M];
ll head[N];
inline void add(ll x,ll y,ll z){
A[++TOT]=(node){y,z,head[x]}; head[x]=TOT;
}
void tarjan(ll u,ll f){
dfn[u]=low[u]=++cnt;
for(ll i=head[u];i;i=A[i].next){
ll y=A[i].y;
if (y==f) continue;
if (!dfn[y]){
father[y]=u; b[y]=A[i].z;
tarjan(y,u);
low[u]=mymin(low[u],low[y]);
} else low[u]=mymin(low[u],dfn[y]);
if (low[y]<=dfn[u]) continue;
insert(u,y,A[i].z);
}
for(ll i=head[u];i;i=A[i].next){
ll y=A[i].y;
if (father[y]==u||dfn[y]<=dfn[u]) continue;
square_point(u,y,A[i].z);
}
}
inline ll find(ll u,ll f){
ll res=0;
while (top[u]!=top[f]) res=top[u],u=father[top[u]];
return u==f?res:son[f];
}
int main(){
n=get(); m=get(); ext=n;
for(ll i=1,s1,s2,s3;i<=m;i++) s1=get(),s2=get(),s3=get(),add(s1,s2,s3),add(s2,s1,s3);
tarjan(1,0);
dfs1(R,0); dfs2(R,R); Q=get();
while (Q--){
ll u=get(),v=get(),p=lca(u,v);
if (p<=n) ans=dis[u]+dis[v]-(dis[p]<<1);
else {
ll RA=find(u,p),RB=find(v,p);
ans=dis[u]+dis[v]-dis[RA]-dis[RB];
if (sum[RA]<sum[RB]) myswap(RA,RB);
ans+=mymin(sum[RA]-sum[RB],sum[p]+sum[RB]-sum[RA]);
}
write(ans); putchar('\n');
}
return 0;
}