meaning of the title
Now there is a cactus, and the edge right of article \ (i \) is \ (i \). The point pair \ ((u,v) \) is good if and only if \ (u \) can reach \ (v \) through the path of edge weight single increase. For each \ (u \), count how many \ ((u,v) \) are good\ (n,m\leq 5\times 10^5\).
Problem solution
Here, the derivation of the official problem solution is adopted. We first transformed a relatively vivid topic:
- Now there is a cactus on the edge of a tree. There is a mouse at each node. Initially, each mouse has a different infectious disease. Then enumerate each edge in reverse order, let the mice at both ends of the edge infect each other, and ask how many different infectious diseases each mouse has in the end.
It is easy to notice that an infectious disease can infect a mouse if and only if the infectious disease can reach the mouse through the path of edge weight single reduction. Therefore, the meaning of the question is the same as the original question.
First consider the simple situation of trees. At this time, it is obviously impossible for a mouse to be repeatedly infected with a disease twice. We directly record \ (f_i \) as the number of infectious diseases of the current \ (I \) mouse, and enumerate each side \ ((u,v) \) according to the input reverse order, then the new \ (f '\) is: \ (f' _uu = f '_v = f_ + f_v \).
The premise of the above method is that there is no public infectious disease before the two mice infect each other. However, when there is a ring in the figure, we need to subtract the public infectious disease. Specifically, let \ ((u,v) \) be the edge with the least edge weight on the ring. When it is enumerated, \ (u \) and \ (v \) are connected on the graph; If an edge \ (e \) can reach both \ (u \) and \ (v \) through a single subtraction path, then \ (u,v \) two mice share all the diseases transmitted on \ (e \), and we should subtract it.
In implementation, we first find all rings and find their minimum and maximum edges; If the largest edge can pass through the path of simple subtraction to the two endpoints of the smallest edge, we record it. Next, we enumerate each edge in reverse order, transfer it in the above way, and record the time \ (f_u+f_v \) when enumerating to this edge for subsequent subtraction.
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; int v[N],tot=1; vector<int>to[N]; bool vis[N],vvis[N]; vector<int>cy[N];int cnt=0; pair<int,int> ss(int x,int fa){ vis[x]=1; pair<int,int> ret={0,0}; for(int i:to[x]){ int v=::v[i]; if(v==fa)continue; if(vvis[i]||vvis[i^1])continue; vvis[i]=1; if(vis[v]){ ++cnt; cy[cnt].push_back(i); ret={v,cnt}; continue; } auto t=ss(v,x); if(t.second){ cy[t.second].push_back(i); if(x!=t.first)ret=t; } } return ret; } int q[N],f[N],g[N]; int main(){ ios::sync_with_stdio(0); cin.tie(0); int n,m; cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; ++tot;v[tot]=y;to[x].push_back(tot); ++tot;v[tot]=x;to[y].push_back(tot); } ss(1,0); if(cnt!=m-n+1)return cnt-(m-n+1); for(int i=1;i<=cnt;i++) for(int j=0;j<cy[i].size();j++){ if(v[cy[i][j]^1]!=v[cy[i][(j+1)%cy[i].size()]]) return i*100; } for(int i=1;i<=cnt;i++){ int mx=max_element(cy[i].begin(),cy[i].end())-cy[i].begin(); rotate(cy[i].begin(),cy[i].begin()+mx,cy[i].end()); int mn=min_element(cy[i].begin(),cy[i].end())-cy[i].begin(); if(is_sorted(cy[i].begin(),cy[i].begin()+mn,greater<int>()) &&is_sorted(cy[i].begin()+mn,cy[i].end())){ q[cy[i][mn]]=cy[i][0]; } } for(int i=1;i<=n;i++)f[i]=1; for(int i=tot;i>=2;i-=2){ int u=v[i],v=::v[i^1]; int x=f[u]+f[v]; f[u]=f[v]=(q[i]+q[i^1]?x-g[q[i]+q[i^1]]:x); g[i^1]=g[i]=f[u]; } for(int i=1;i<=n;i++)cout<<f[i]-1<<" "; }