BZOJ传送门
洛谷传送门
补档计划无题解
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<20|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline int getint(){
re char c;
while(!isdigit(c=gc()));re int num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
}
using namespace IO;
using std::cout;
using std::cerr;
cs int N=1e4+4;
int n,m,q;
int ext;
namespace Tree{
static cs int N=::N<<1;
struct edge{
int to,w;
edge(cs int &_to,cs int &_w):to(_to),w(_w){}
};
std::vector<edge> G[N];
typedef std::vector<edge>::iterator iter;
inline void addedge(int u,int v,int val){
G[u].push_back(edge(v,val));
G[v].push_back(edge(u,val));
}
int fa[N],dep[N],top[N],siz[N],son[N];
int dist[N];
void dfs1(int u){
siz[u]=1;
for(iter re e=G[u].begin();e!=G[u].end();++e)if(e->to!=fa[u]){
dist[e->to]=dist[u]+e->w;
fa[e->to]=u;
dep[e->to]=dep[u]+1;
dfs1(e->to);
siz[u]+=siz[e->to];
if(siz[e->to]>siz[son[u]])son[u]=e->to;
}
}
void dfs2(int u){
if(son[u]){
top[son[u]]=top[u];
dfs2(son[u]);
}
else return ;
for(iter re e=G[u].begin();e!=G[u].end();++e)if(e->to!=fa[u]&&e->to!=son[u]){
top[e->to]=e->to;
dfs2(e->to);
}
}
inline void build(){
dfs1(1);
top[1]=1;
dfs2(1);
}
inline int LCA(int u,int v){
while(top[u]!=top[v])dep[top[u]]<dep[top[v]]?(v=fa[top[v]]):(u=fa[top[u]]);
return dep[u]<dep[v]?u:v;
}
inline int find(int u,int f){
int res;
while(top[u]!=top[f]){
res=top[u];
u=fa[top[u]];
}
return u==f?res:son[f];
}
}
namespace Cactu{
static cs int N=::N;
struct edge{
int to,w;
edge(cs int &_to,cs int &_w):to(_to),w(_w){}
};
std::vector<edge> G[N];
typedef std::vector<edge>::iterator iter;
inline void addedge(int u,int v,int val){
G[u].push_back(edge(v,val));
G[v].push_back(edge(u,val));
}
int w[N],sum[N<<1],fa[N];
int dfn[N],low[N],dfs_clock;
inline void solve(cs int u,cs int v,int val){
++ext;
for(int re i=v;i!=fa[u];i=fa[i]){
sum[i]=val;
val+=w[i];
}
sum[ext]=sum[u];
sum[u]=0;
for(int re i=v;i!=fa[u];i=fa[i]){
int p=std::min(sum[i],sum[ext]-sum[i]);
Tree::addedge(ext,i,p);
}
}
inline void tarjan(int u,int pa){
dfn[u]=low[u]=++dfs_clock;
for(iter re e=G[u].begin();e!=G[u].end();++e)if(e->to!=pa){
int v=e->to;
if(!dfn[v]){
fa[v]=u,w[v]=e->w;
tarjan(v,u);
low[u]=std::min(low[u],low[v]);
}
else low[u]=std::min(low[u],dfn[v]);
if(low[v]>dfn[u])Tree::addedge(u,v,e->w);
}
for(iter re e=G[u].begin();e!=G[u].end();++e)if(fa[e->to]!=u&&dfn[e->to]>dfn[u])solve(u,e->to,e->w);
}
}
inline int query(int u,int v){
int lca=Tree::LCA(u,v);
if(lca<=n)return Tree::dist[u]+Tree::dist[v]-(Tree::dist[lca]<<1);
int fu=Tree::find(u,lca),fv=Tree::find(v,lca);
int tmp=abs(Cactu::sum[fu]-Cactu::sum[fv]);
return Tree::dist[u]+Tree::dist[v]-Tree::dist[fu]-Tree::dist[fv]
+std::min(tmp,Cactu::sum[lca]-tmp);
}
signed main(){
ext=n=getint(),m=getint(),q=getint();
for(int re i=1,u,v,val;i<=m;++i){
u=getint(),v=getint(),val=getint();
Cactu::addedge(u,v,val);
}
Cactu::tarjan(1,0);
Tree::build();
while(q--)cout<<query(getint(),getint())<<"\n";
return 0;
}