# [BZOJ2125]最短路(圆方树DP)

 1 #include<cstdio>
2 #include<algorithm>
3 #define rep(i,l,r) for (int i=l; i<=r; i++)
4 using namespace std;
5
6 const int N=20010;
7 int n,m,Q,u,v,w,tot,tim,top,dep[N],len[N],type[N],stk[N];
8 int dfn[N],low[N],dis[N],lst[N],fa[N][16],sm[N][16];
9
10 struct E{
11     int cnt,h[N],to[N<<1],nxt[N<<1],val[N<<1];
12     void add(int u,int v,int w){ to[++cnt]=v; val[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt; }
13 }G,G1;
14
15 void work(int x,int k){
16     tot++; int t; len[tot]=dis[stk[top]]-dis[x]+lst[stk[top]];
17     do{
18         t=stk[top--];
19         int A=dis[t]-dis[x],B=len[tot]-A;
21     }while (t!=k);
23 }
24
25 void Tarjan(int x,int pre){
26     //printf("%d\n",x);
27     dfn[x]=low[x]=++tim; stk[++top]=x;
28     for (int i=G.h[x],k; i; i=G.nxt[i]){
29         if ((k=G.to[i])==pre) continue;
30         if (!dfn[k]){
31             dis[k]=dis[x]+G.val[i]; Tarjan(k,x);
32             //printf("%d %d %d %d\n",x,k,dfn[x],low[k]);
34             else if (low[k]==dfn[x]) work(x,k);
35             low[x]=min(low[x],low[k]);
36         }else low[x]=min(low[x],dfn[k]),lst[x]=G.val[i];
37     }
38 }
39
40 void dfs(int x,int pre){
41     for (int i=G1.h[x],k; i; i=G1.nxt[i])
42         fa[k=G1.to[i]][0]=x,dep[k]=dep[x]+1,sm[k][0]=G1.val[i],dfs(k,x);
43 }
44
45 int lca(int u,int v){
46     if (dep[u]<dep[v]) swap(u,v);
47     int t=dep[u]-dep[v],res=0;
48     for (int i=15; ~i; i--) if (t&(1<<i)) res+=sm[u][i],u=fa[u][i];
49     if (u==v) return res;
50     for (int i=15; ~i; i--) if (fa[u][i]!=fa[v][i])
51         res+=sm[u][i]+sm[v][i],u=fa[u][i],v=fa[v][i];
52     if (fa[u][0]<=n) return sm[u][0]+sm[v][0]+res;
53     int A=sm[u][0],B=sm[v][0],mn;
54     if (type[u]==type[v]) mn=min(abs(A-B),len[fa[u][0]]-abs(A-B));
55         else mn=min(A+B,len[fa[u][0]]-A-B);
56     return res+mn;
57 }
58
59 int main(){
60     freopen("bzoj2125.in","r",stdin);
61     freopen("bzoj2125.out","w",stdout);
62     scanf("%d%d%d",&n,&m,&Q); tot=n;
70 }