Beginning to think not square the circle by means of a tree, thinking very confusing, I thought for a long time to calm down and find this question is not a simple question to discuss classified Well ...
The subject is not difficult, discuss two cases:
Set the current point to an intermediate point (dot)
- After entering starting from a sub-tree to an intermediate point son son into another subtree.
- After entering the starting point from sub-tree of a son to the intermediate point and still back the son subtree (the equivalent of a child's problems)
- Then for his son (square dots) directly accumulate, father (square dots) to deduct the impact of the current sub-tree.
code:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define N 200006 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; vector<int>G[N]; ll ans; int edges,tim,tot,n,m,fr,SIZE; int hd[N<<1],to[N<<1],nex[N<<1],dfn[N],low[N],S[N],deg[N],size[N]; ll g[N],F[N]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void tarjan(int x) { dfn[x]=low[x]=++tim; S[++fr]=x; ++SIZE; for(int i=hd[x];i;i=nex[i]) { int y=to[i]; if(!dfn[y]) { tarjan(y); low[x]=min(low[x],low[y]); if(low[y]>=dfn[x]) { ++tot; G[x].push_back(tot); G[tot].push_back(x); ++deg[tot]; for(int p=0;p!=y;--fr) { p=S[fr]; ++deg[tot]; G[tot].push_back(p); G[p].push_back(tot); } } } else { low[x]=min(low[x],dfn[y]); } } } void dfs(int x,int ff) { size[x]=(x<=n); for(int i=0;i<G[x].size();++i) { int y=G[x][i]; if(y==ff) continue; dfs(y,x); size[x]+=size[y]; } } void solve(int x,int ff) { if(x<=n) { int cu=0; for(int i=0;i<G[x].size();++i) { int y=G[x][i]; if(y==ff) cu=SIZE-size[x]; else cu=size[y]; ans+=1ll*cu*(SIZE-cu-1); } if(ff) { ans+=g[ff]-1ll*size[x]*SIZE; ans-=1ll*size[x]*(SIZE-2*size[x]); } } else { for(int i=0;i<G[x].size();++i) { int y=G[x][i]; if(y==ff) continue; F[x]+=1ll*size[y]*(size[x]-size[y]); g[x]+=1ll*size[y]*(SIZE-size[y]); } g[x]+=1ll*size[x]*(SIZE-size[x]); ans+=1ll*F[x]; } for(int i=0;i<G[x].size();++i) if(G[x][i]!=ff) solve(G[x][i],x); } int main() { // setIO("input"); scanf("%d%d",&n,&m); tot=n; for(int i=1;i<=m;++i) { int x,y; scanf("%d%d",&x,&y); add(x,y),add(y,x); } for(int i=1;i<=n;++i) { if(!dfn[i]) { tim=SIZE=fr=0; tarjan(i); dfs(i,0); solve(i,0); } } printf("%lld\n",ans); return 0; }