待填。。。现存代码
仙人掌的圆方树
#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define per(i,x,y) for(int i=x;i>=y;--i)
#define mar(o) for(int E=fst[o];E;E=e[E].nxt)
#define marz(o) for(int E=fstz[o];E;E=ez[E].nxt)
#define v e[E].to
#define vz ez[E].to
using namespace std;
const int n7=20123,m7=40123;
struct dino{int to,nxt,w;}e[m7],ez[m7];
int n,m,T,dcnt,ecnt,t,fst[n7],fstz[n7];
int dfn[n7],low[n7],fa[n7],dw[n7],cir[n7],s[n7];
int dep[n7],fc[n7][21],snp,snq;
int rd(){
int shu=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))shu=(shu<<1)+(shu<<3)+ch-'0',ch=getchar();
return shu;
}
void Dedge(int sta,int edn,int w,dino *eh,int *fsth){
ecnt++;
eh[ecnt]=(dino){edn,fsth[sta],w};
fsth[sta]=ecnt;
}
void edge(int sta,int edn,int w,dino *eh,int *fsth){
Dedge(sta,edn,w,eh,fsth),Dedge(edn,sta,w,eh,fsth);
}
void calc(int o1,int o2,int lasw){
int tot=lasw;
for(int o=o2;o!=o1;o=fa[o]){
cir[o]=tot,tot+=dw[o];
}
dcnt++,cir[dcnt]=tot;
for(int o=o2;o!=o1;o=fa[o]){
edge(dcnt,o,min(cir[o],tot-cir[o]),ez,fstz);
}
edge(dcnt,o1,0,ez,fstz);
}
void tarjan(int o){
t++,dfn[o]=low[o]=t;
mar(o){
if(v==fa[o])continue;
if(!dfn[v]){
fa[v]=o,dw[v]=e[E].w;
tarjan(v);
low[o]=min(low[o],low[v]);
}
low[o]=min(low[o],dfn[v]);
if(low[v]>dfn[o]){
edge(o,v,e[E].w,ez,fstz);
}
}
mar(o){
if(fa[v]!=o&&dfn[v]>dfn[o])calc(o,v,e[E].w);
}
}
void dfs(int o){
rep(i,1,16)fc[o][i]=fc[ fc[o][i-1] ][i-1];
marz(o){
if(dep[vz])continue;
dep[vz]=dep[o]+1;
fc[vz][0]=o,s[vz]=s[o]+ez[E].w;
dfs(vz);
}
}
int Dlca(int p,int q){
if(dep[p]<dep[q])p^=q^=p^=q;
per(i,16,0){
if(dep[ fc[p][i] ]>=dep[q])p=fc[p][i];
}
if(p==q)return p;
per(i,16,0){
if(fc[p][i]!=fc[q][i])p=fc[p][i],q=fc[q][i];
}
snp=p,snq=q;
return fc[p][0];
}
int main(){
n=dcnt=rd(),m=rd(),T=rd();
rep(i,1,m){
int sta=rd(),edn=rd(),w=rd();
edge(sta,edn,w,e,fst);
}
ecnt=0;
tarjan(1);
dep[1]=1,dfs(1);
while(T--){
int p=rd(),q=rd();
int lca=Dlca(p,q),ans;
if(lca<=n)ans=s[p]+s[q]-2*s[lca];
else{
ans=s[p]-s[snp]+s[q]-s[snq];
if(cir[snp]<cir[snq])snp^=snq^=snp^=snq;
ans=ans+min(cir[snp]-cir[snq],cir[lca]-cir[snp]+cir[snq]);
}
printf("%d
",ans);
}
return 0;
}
一般图的圆方树
铁人两项
#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define mar(o) for(int E=fst[o];E;E=e[E].nxt)
#define marz(o) for(int E=fstz[o];E;E=ez[E].nxt)
#define v e[E].to
#define vz ez[E].to
#define lon long long
using namespace std;
const int n7=101234,z7=201234,m7=401234;
struct dino{int to,nxt;}e[m7],ez[m7];
int n,m,dcnt,ecnt,fst[n7],fstz[z7],t,dfn[n7],low[n7],top,sak[n7];
int val[z7],wei[z7],num,siz[z7];
lon ans;bool in[n7];
int rd(){
int shu=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))shu=(shu<<1)+(shu<<3)+ch-'0',ch=getchar();
return shu;
}
void edge(int sta,int edn,int *fsth,dino *eh){
ecnt++;
eh[ecnt]=(dino){edn,fsth[sta]};
fsth[sta]=ecnt;
}
void tarjan(int o){
num++;
t++,dfn[o]=low[o]=t;
top++,sak[top]=o,in[o]=1;
mar(o){
if(!dfn[v]){
tarjan(v);
low[o]=min(low[o],low[v]);
if(low[v]!=dfn[o])continue;
dcnt++;
while(sak[top+1]!=v){
edge(sak[top],dcnt,fstz,ez);
edge(dcnt,sak[top],fstz,ez);
val[ sak[top] ]=-1;
in[ sak[top] ]=0;
val[dcnt]++,top--;
}
val[dcnt]++,val[o]=-1;
edge(o,dcnt,fstz,ez);
edge(dcnt,o,fstz,ez);
}
else if(in[v])low[o]=min(low[o],dfn[v]);
}
}
void dfs(int o,int fa){
if(o<=n)siz[o]=1;
marz(o){
if(vz==fa)continue;
dfs(vz,o);
ans=ans+2ll*siz[o]*siz[vz]*val[o];
siz[o]+=siz[vz];
}
ans=ans+2ll*siz[o]*(num-siz[o])*val[o];
}
int main(){
n=dcnt=rd(),m=rd();
rep(i,1,m){
int sta=rd(),edn=rd();
edge(sta,edn,fst,e);
edge(edn,sta,fst,e);
}
ecnt=0;
rep(i,1,n){
if(dfn[i])continue;
num=0,tarjan(i),dfs(i,0);
}
printf("%lld",ans);
return 0;
}