版权声明:虽然是个蒟蒻但是转载还是要说一声的哟 https://blog.csdn.net/jpwang8/article/details/83385416
Description
如今,路由器和交换机构建起了互联网的骨架。处在互联网的骨干位置的
核心路由器典型的要处理100Gbit/s的网络流量。他们每天都生活在巨大的压力
之下。
小强建立了一个模型。这世界上有N个网络设备,他们之间有M个双向的
链接。这个世界是连通的。在一段时间里,有Q个数据包要从一个网络设备发
送到另一个网络设备。
一个网络设备承受的压力有多大呢?很显然,这取决于Q个数据包各自走
的路径。不过,某些数据包无论走什么路径都不可避免的要通过某些网络设
备。
你要计算:对每个网络设备,必须通过(包括起点、终点)他的数据包有
多少个?
对于40%的数据,N,M,Q≤2000
对于60%的数据,N,M,Q≤40000
对于100%的数据,N≤100000,M,Q≤200000
Solution
一开始写了缩点发现这样不太好做。。
考虑建广义圆方树,路径上的必经点显然是树上路径中的圆点
由于做了很多天的树链剖分模拟赛已经吐了,我们今天用差分的做法。
对于一条路径修改(x,y),我们在x、y处+1,在lca和fa[lca]处-1,然后离线求和即可
好像没啥好说的。。。
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
const int N=200005;
std:: stack <int> stack;
struct Graph {
struct edge {int y,next;} e[N*2];
int ls[N],edCnt;
Graph() {fill(ls,0); edCnt=1;}
edge operator [](int x) const {
return e[x];
}
void add_edge(int x,int y) {
e[++edCnt]=(edge) {y,ls[x]}; ls[x]=edCnt;
e[++edCnt]=(edge) {x,ls[y]}; ls[y]=edCnt;
}
} G,T;
int bl[N],size[N],fa[N],dep[N];
int dfn[N],low[N];
int s[N],tot;
bool vis[N];
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
void dfs(int now,int from) {
dfn[now]=low[now]=++dfn[0]; vis[now]=true;
for (int i=G.ls[now];i;i=G[i].next) {
if ((i^1)==from) continue;
if (!dfn[G[i].y]) {
stack.push(i); dfs(G[i].y,i);
low[now]=std:: min(low[now],low[G[i].y]);
if (dfn[now]<=low[G[i].y]) {
int y=0; tot++;
while (y!=i) {
y=stack.top(); stack.pop();
T.add_edge(tot,G[y].y);
}
T.add_edge(now,tot);
}
} else if (vis[G[i].y]) low[now]=std:: min(low[now],dfn[G[i].y]);
}
vis[now]=false;
}
void dfs1(int now) {
size[now]=1;
for (int i=T.ls[now];i;i=T[i].next) {
if (T[i].y==fa[now]) continue;
fa[T[i].y]=now; dep[T[i].y]=dep[now]+1;
dfs1(T[i].y);
size[now]+=size[T[i].y];
}
}
void dfs2(int now,int up) {
bl[now]=up; int mx=0;
for (int i=T.ls[now];i;i=T[i].next) {
if (T[i].y!=fa[now]&&size[T[i].y]>size[mx]) mx=T[i].y;
}
if (!mx) return ;
dfs2(mx,up);
for (int i=T.ls[now];i;i=T[i].next) {
if (T[i].y!=fa[now]&&T[i].y!=mx) dfs2(T[i].y,T[i].y);
}
}
int get_lca(int x,int y) {
for (;bl[x]!=bl[y];) {
(dep[bl[x]]<dep[bl[y]])?(std:: swap(x,y)):(void)0;
x=fa[bl[x]];
}
return dep[x]<dep[y]?x:y;
}
void dfs3(int now) {
for (int i=T.ls[now];i;i=T[i].next) {
if (T[i].y==fa[now]) continue;
dfs3(T[i].y);
s[now]+=s[T[i].y];
}
}
int main(void) {
int n=read(),m=read(),q=read(); tot=n;
rep(i,1,m) G.add_edge(read(),read());
dfs(1,0);
dfs1(1); dfs2(1,1);
rep(i,1,q) {
int x=read(),y=read();
int lca=get_lca(x,y);
s[x]++; s[y]++;
s[lca]--; s[fa[lca]]--;
}
dfs3(1);
rep(i,1,n) printf("%d\n", s[i]);
return 0;
}