# 【BZOJ2125】最短路

http://darkbzoj.tk/problem/2125

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<cstdlib>
#include<stack>
#define ri register int
#define N 50500
#define M 105000
using namespace std;

int tn,n,m,q;

int ret=0,f=0; char ch=getchar();
while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
while (ch>='0'&& ch<='9') ret*=10,ret+=ch-'0',ch=getchar();
return f?-ret:ret;
}

int ciren[N];
bool zheng[N];

struct tree {
vector<int> to[N<<1],len[N<<1];
void add_edge(int u,int v,int w) {
to[v].push_back(u); len[v].push_back(w);
}
int fa[N<<1],f[N<<1][19],d[N<<1];
int sL[N<<1];
void maketree(int x,int ff) {
f[x][0]=fa[x]=ff;
for (ri i=1;i<=18;i++) f[x][i]=f[f[x][i-1]][i-1];
for (ri i=0;i<to[x].size();i++) {
int y=to[x][i];
sL[y]=sL[x]+len[x][i]; d[y]=d[x]+1;
maketree(y,x);
}
}
int lca(int x,int y) {
if (d[x]<d[y]) swap(x,y);
for (ri i=18;i>=0;i--) if (d[f[x][i]]>=d[y]) x=f[x][i];
if (x==y) return x;
for (ri i=18;i>=0;i--) if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return fa[x];
}
int jump(int x,int y) {
for (ri i=18;i>=0;i--) if (d[f[x][i]]>d[y]) x=f[x][i];
return x;
}
int query(int x,int y) {
int t=lca(x,y);
if (t>tn) {
int x0=jump(x,t);
int y0=jump(y,t);
int ans=sL[x]-sL[x0]+sL[y]-sL[y0];
if (zheng[x0]!=zheng[y0]) {
ans+=min(sL[x0]+sL[y0]-2*sL[t],ciren[t]-sL[x0]-sL[y0]+2*sL[t]);
}
else {
ans+=min(abs(sL[x0]-sL[y0]),ciren[t]-abs(sL[x0]-sL[y0]));
}
return ans;
}
else return sL[x]+sL[y]-2*sL[t];
}
} T;

struct graph {
vector<int> to[N],len[N];
int dfn[N],low[N],dr[N];
int cnt;
stack<int> s;
void add_edge(int u,int v,int w) {
to[u].push_back(v); len[u].push_back(w);
to[v].push_back(u); len[v].push_back(w);
}
void tarjan(int x) {
dfn[x]=low[x]=++cnt;
s.push(x);
for (ri i=0;i<to[x].size();i++) {
int y=to[x][i];
if (dfn[y]) {
low[x]=min(low[x],dfn[y]);
}
else {
dr[y]=dr[x]+len[x][i];
tarjan(y);
if (low[y]>=dfn[x]) {
++n;
int t=s.top(),cirl=dr[t]-dr[x];
for (ri j=0;j<to[t].size();j++) if (to[t][j]==x) {cirl+=len[t][j]; break;}
ciren[n]=cirl;
do {
t=s.top(); s.pop();
if (dr[t]-dr[x]>cirl-dr[t]+dr[x]) zheng[t]=1;
}
while (t!=y);
}
low[x]=min(low[x],low[y]);
}
}
}
} G;

int main() {
int u,v,w;
for (ri i=1;i<=m;i++) {
}