分析:
不多解释,
v-DCC缩点的板子+树上差分+LCA
v-DCC的板子得好好学啊!
受益匪浅的图(来自zkt)
有虚点,注意范围
#include<cstdio> #include<queue> #include<iostream> #include<cmath> #include<cstring> #include<vector> #define MAXN 200010 using namespace std; inline int minn(int a,int b){return a<b?a:b;} struct rr{ int inext,to; }bl[MAXN*10],tbl[MAXN*10]; int thead[MAXN],ttot,head[MAXN],itot; void add(int x,int y){ bl[++itot].to=y; bl[itot].inext=head[x]; head[x]=itot; } void tadd(int x,int y){ tbl[++ttot].to=y; tbl[ttot].inext=thead[x]; thead[x]=ttot; } int root,N,M,Q; int dfn[MAXN],low[MAXN],num; bool cut[MAXN]; int belong[MAXN],tot; int stack[MAXN],top; vector<int >dcc[MAXN]; void tarjan(int u,int fa){ dfn[u]=low[u]=++num; stack[++top]=u; if(u==root&&!head[u]){ --top; dcc[++tot].push_back(u); return ; } int tto,flag=0; for(int i=head[u];i;i=bl[i].inext){ if(bl[i].to==fa)continue; if(!dfn[tto=bl[i].to]){ tarjan(tto,u); low[u]=minn(low[u],low[tto]); if(low[tto]>=dfn[u]){ ++flag; if(u!=root||flag>=2) cut[u]=true; ++tot; int tan=stack[top]; while(tan!=tto){ dcc[tot].push_back(tan); tan=stack[--top]; } --top; dcc[tot].push_back(tto); dcc[tot].push_back(u); } } else low[u]=minn(low[u],dfn[tto]); } return ; } int ys[MAXN]; void init(){ int x,y; for(int i=1;i<=N;++i) if(cut[i]){ belong[i]=++tot; ys[tot]=i; } for(int i=1;i<=tot;++i) for(int k=0;k<dcc[i].size();++k) if(!cut[y=dcc[i][k]])belong[y]=i; else tadd(i,belong[y]),tadd(belong[y],i); } int bin[20]; bool fw[MAXN]; int f[MAXN][20],sd[MAXN]; queue<int >dd; void bfs(){ int tto; dd.push(belong[root]);fw[belong[root]]=true; sd[belong[root]]=1; while(!dd.empty()){ int ltop=dd.front();dd.pop(); for(int i=thead[ltop];i;i=tbl[i].inext){ if(fw[tto=tbl[i].to])continue; fw[tto]=true; dd.push(tto); sd[tto]=sd[ltop]+1; f[tto][0]=ltop; for(int j=1;bin[j]<=sd[tto];++j) f[tto][j]=f[f[tto][j-1]][j-1]; } } memset(fw,0,sizeof(fw)); } int LCA(int x,int y){ if(sd[x]<sd[y])swap(x,y); for(int j=19;j>=0;--j) if(f[x][j]&&sd[f[x][j]]>=sd[y]) x=f[x][j]; if(x==y)return x; for(int j=19;j>=0;--j) if(f[x][j]&&f[y][j]&&f[x][j]!=f[y][j]) x=f[x][j],y=f[y][j]; return f[x][0]; } int zui[MAXN],cha[MAXN]; void dfs(int u){ fw[u]=true; int tto; for(int i=thead[u];i;i=tbl[i].inext){ if(fw[tto=tbl[i].to])continue; dfs(tto); cha[u]+=cha[tto]; } if(ys[u])zui[ys[u]]+=cha[u]; return ; } int main(){ root=bin[0]=1; for(int i=1;i<=19;++i)bin[i]=bin[i-1]<<1; scanf("%d%d%d",&N,&M,&Q); int ai,bi; for(int i=1;i<=M;++i){ scanf("%d%d",&ai,&bi); if(ai==bi)continue; add(ai,bi);add(bi,ai); } tarjan(root,0); init(); bfs(); int lca; while(Q){ --Q; scanf("%d%d",&ai,&bi); if(!cut[ai])++zui[ai]; if(!cut[bi])++zui[bi]; ai=belong[ai];bi=belong[bi]; lca=LCA(ai,bi); ++cha[ai];++cha[bi]; --cha[lca];--cha[f[lca][0]]; } dfs(belong[root]); for(int i=1;i<=N;++i) printf("%d\n",zui[i]); }