1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| const int maxn=100005;
struct Edge { int from,to,dist; Edge(int x=0,int y=0,int v=0):from(x),to(y),dist(v) {} };
struct St { int u,v,dist; St(int x=0,int y=0,int va=0):u(x),v(y),dist(va) {} };
vector<Edge> edges[maxn],tree[maxn]; vector<int> Circle[maxn]; stack<St> S;
int step=0,Lowlink[maxn],Dfn[maxn],BCC=0,New,Length[maxn],f[maxn],Belong[maxn],vst[maxn],Square[maxn];
void AddEdge(int x,int y,int v) {edges[x].push_back(Edge(x,y,v));}
void AddEdge2(int x,int y,int v) {tree[x].push_back(Edge(x,y,v));}
void Tarjan(int Now,int fa) { step++; Lowlink[Now]=Dfn[Now]=step; for(Edge &e:edges[Now]) { int Next=e.to; if(!Dfn[Next]) { S.push(St(Now,Next,e.dist)); Tarjan(Next,Now); Lowlink[Now]=min(Lowlink[Now],Lowlink[Next]); if(Dfn[Now]<Lowlink[Next])AddEdge2(Now,Next,e.dist),S.pop(); else if(Dfn[Now]==Lowlink[Next]) { BCC++; AddEdge2(Now,++New,0); Square[New]=1; while(!S.empty()) { int u=S.top().u,v=S.top().v,dist=S.top().dist;S.pop(); Length[BCC]+=dist; f[u]=f[v]+dist; if(u!=Now)Belong[u]=BCC,Circle[New].push_back(u); if(u==Now&&v==Next)break; } for(int Next:Circle[New])AddEdge2(New,Next,min(abs(f[Next]-f[Now]),Length[BCC]-abs(f[Next]-f[Now]))); } } else if(Next!=fa&&Lowlink[Now]>Dfn[Next]) { Lowlink[Now]=Dfn[Next]; S.push(St(Now,Next,e.dist)); } } }
|