题解:
建出圆方树
先求点双,然后每个点向点双代表的方点连边
然后树上差分一下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
const int maxn=400009;
typedef pair<int,int> fuck;
int n,m,t;
int rx[maxn],ry[maxn];
int cntedge=0;
int head[maxn]={0};
int to[maxn<<1],nex[maxn<<1];
void Addedge(int x,int y){
nex[++cntedge]=head[x];
to[cntedge]=y;
head[x]=cntedge;
}
int bcccnt=0,dfsclock=0;
int pre[maxn],lowlink[maxn],bccnum[maxn];
stack<fuck>S;
vector<int>B[maxn];
void Dfs(int u,int fa){
pre[u]=lowlink[u]=++dfsclock;
for(int i=head[u];i;i=nex[i]){
int v=to[i];
if(v==fa)continue;
if(!pre[v]){
S.push(make_pair(u,to[i]));
Dfs(v,u);
lowlink[u]=min(lowlink[u],lowlink[v]);
if(lowlink[v]>=pre[u]){
++bcccnt;
for(;;){
pair<int,int>P=S.top();S.pop();
if(bccnum[P.first]!=bcccnt){
bccnum[P.first]=bcccnt;
B[bcccnt].push_back(P.first);
}
if(bccnum[P.second]!=bcccnt){
bccnum[P.second]=bcccnt;
B[bcccnt].push_back(P.second);
}
if(P==make_pair(u,v))break;
}
}
}else{
lowlink[u]=min(lowlink[u],pre[v]);
}
}
}
int totn;
int f[maxn][20],dep[maxn];
void Dfs2(int x,int fa){
f[x][0]=fa;
dep[x]=dep[fa]+1;
for(int i=head[x];i;i=nex[i]){
if(to[i]==fa)continue;
Dfs2(to[i],x);
}
}
void LCAinit(){
for(int j=1;j<=19;++j){
for(int i=1;i<=totn;++i){
f[i][j]=f[f[i][j-1]][j-1];
}
}
}
int Getlca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
for(int j=19;j>=0;--j){
if(dep[f[u][j]]>=dep[v]){
u=f[u][j];
}
}
if(u==v)return u;
for(int j=19;j>=0;--j){
if(f[u][j]!=f[v][j]){
u=f[u][j];v=f[v][j];
}
}
return f[u][0];
}
int mar[maxn];
void Dp(int x,int fa){
for(int i=head[x];i;i=nex[i]){
if(to[i]==fa)continue;
Dp(to[i],x);
mar[x]+=mar[to[i]];
}
}
int father[maxn];
int Getf(int x){
if(father[x]==x)return x;
return father[x]=Getf(father[x]);
}
void Unionn(int x,int y){
int fx=Getf(x);
int fy=Getf(y);
if(fx!=fy)father[fx]=fy;
}
int main(){
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=m;++i){
scanf("%d%d",&rx[i],&ry[i]);
Addedge(rx[i],ry[i]);
Addedge(ry[i],rx[i]);
}
Dfs(1,0);
cntedge=0;
memset(head,0,sizeof(head));
totn=n;
for(int i=1;i<=n+bcccnt;++i)father[i]=i;
for(int u=1;u<=bcccnt;++u){
++totn;
for(int i=0;i<B[u].size();++i){
int v=B[u][i];
Addedge(v,totn);
Addedge(totn,v);
Unionn(totn,v);
}
}
// for(int i=1;i<=m;++i){
// if(Getf(rx[i])!=Getf(ry[i])){
// Addedge(rx[i],ry[i]);
// Addedge(ry[i],rx[i]);
// Unionn(rx[i],ry[i]);
// }
// }
Dfs2(1,0);
LCAinit();
while(t--){
int x,y;
scanf("%d%d",&x,&y);
int lca=Getlca(x,y);
mar[x]++;mar[y]++;mar[lca]--;mar[f[lca][0]]--;
}
Dp(1,0);
for(int i=1;i<=n;++i)printf("%d\n",mar[i]);
return 0;
}