P8456 「SWTR-8」地地铁铁 做题记录

P8456 「SWTR-8」地地铁铁

Description

给定一张 \(n\) 个点,\(m\) 条边的无向连通图。每条边标有 Dd

定义无序点对 \((x, y)\) 是「铁的」,当且仅当 \(x \neq y\)\(x, y\) 之间存在同时出现 Dd 的简单路径。

小 A 深知自由组合定律 DdTt 的重要性,所以他让你对这样的点对计数。

\(2\leq n \leq 4\times 10 ^ 5\)\(n - 1\leq m\leq 10 ^ 6\)

Solution

下面称 D\(1\)d\(0\)

首先需要知道点双连通图的一些重要性质: 双连通图性质 - XP3301_Pipi - 博客园

考虑容斥,用 \(\binom n 2\) 减去不合法的。

不合法的点对 \((x,y)\) 一定符合以下三种之一:

  1. \(x,y\) 之间路径上的边全部为 \(0\)
  2. \(x,y\) 之间路径上的边全部为 \(1\)
  3. \(x,y\) 之间只存在全部为 \(0\) 和全部为 \(1\) 的路径。

Part I

考虑 \(x,y\) 之间路径上的边全部为 \(0\) 的点对。

若点双 \(G\) 里面存在 \(1\),那么 \(G\) 内或者经过 \(G\) 的点对都不合法。

我们建出圆方树,删去不合法的方点。对于剩下的每一个连通块,设其圆点个数为 \(c\),则贡献为 \(\binom c 2\)

\(x,y\) 之间路径上的边全部为 \(1\) 的情况也是类似的。

Part II

考虑 \(x,y\) 之间只存在全部为 \(0\) 和全部为 \(1\) 的路径。

Lemma 1

\(x,y\) 属于不同点双,则必定不满足条件。

\(x,y\) 间一条全 \(0\) 路径为 \(P_0\),一条全 \(1\) 路径为 \(P_1\)\(P_0,P_1\) 一定在中间某个割点处相交,在此处交换后面的对应片段可以得到 \(01\) 路径。

Lemma 2

对于一个点双 \(G\),其内部最多有一对满足条件的点对。

\(G\) 中存在两对点对 \((u,v),(x,y)\) 满足条件。

  1. 两个点对有一个公用点。设 \(v=y\)

    任取 \((u,v),(x,y)\) 间两条不同色的纯色路径拼成的环,设为 \(P,Q\)

    删去 \(y\) 点后,\(P,Q\) 之间必定仍然联通,也就是存在一条连接它们的路径。

    如图,可以通过它得到一条标为黑色的 \(01\) 路径。

  2. 两个点对间没有公用点。

    那么 \(P,Q\) 之间一定存在两条连接它们的路径,也可以通过他们得到一条黑色的 \(01\) 路径:

Lemma 3

对于一个满足条件的点对 \((x,y)\),把 \(x,y\) 之间被 \(0\) 路径覆盖的点加入集合 \(S_0\) 中,把 \(x,y\) 之间被 \(1\) 路径覆盖的点加入集合 \(S_1\) 中。设点的全集为 \(S\)

  1. \(S_0\cap S_1=\{x,y\}\),且 \(S_0,S_1\) 之间无边。

    \(u\in(S_0\cap S_1)\)\(u\ne x,u\ne y\),则存在经过 \(x\)\(01\) 路径。

    \(S_0,S_1\) 间存在一条边 \(e\),则存在经过 \(e\)\(01\) 路径。

  2. \(S_0\cup S_1=S\)

    对于点双内任意一点 \(z\) 满足 \(z\ne x\land z\ne y\),一定存在一条简单路径 \(x\rightarrow z\rightarrow y\),则 \(z\) 一定被某一条同色路径覆盖。

Lemma 4

在点双 \(G\) 内部,存在这样的 \((x,y)\) 的充要条件是 \(G\) 内恰好存在两个点 \(x,y\) 同时有 \(01\) 出边。

先证充分性:拿出四条边 \((x,u_0,0),(x,u_1,1),(v_0,y,0),(v_1,y,1)\)\(u_0,v_0\) 之间的路径一定全为 \(0\)\(u_1,v_1\) 之间的路径一定全为 \(1\),则 \((x,y)\) 满足条件。

再证必要性:由引理 3 可证。

维护出每个点双内恰好存在两个点 \(x,y\) 同时有 \(01\) 出边的数量即可。

int n,m;
int head[N],tot;

struct Edge{
	int to,nxt;
}edge[M];

int dfn[N],low[N],num,tim,fa[N],U[M],V[M],W[M];
int c[N],v0[N],v1[N],w0[N],w1[N];
stack<int> path;
vector<int> e[N],s[N];

void Add(int u,int v){
	edge[++tot]={v,head[u]};
	head[u]=tot;
}

void Tarjan(int x){
	dfn[x]=low[x]=++tim;
	path.push(x);
	for(int i=head[x];i;i=edge[i].nxt){
		int t=edge[i].to;
		if(!dfn[t]){
			Tarjan(t);
			Ckmin(low[x],low[t]);
			if(low[t]>=dfn[x]){
				num++; int p;
				do{
					p=path.top(); path.pop();
					e[num].push_back(p);
					e[p].push_back(num);
				}while(p!=t);
				e[num].push_back(x);
				e[x].push_back(num);
			}
		}
		else Ckmin(low[x],dfn[t]);
	}
}

void dfs1(int x,int pr){
	fa[x]=pr;
	for(int t:e[x]){
		if(t==pr) continue;
		dfs1(t,x);
	}
}

struct DSU{
	int fa[N],siz[N];
	
	void Init(){
		for(int i=1;i<=num;i++) fa[i]=i;
		for(int i=1;i<=num;i++) siz[i]=(i<=n);
	}
	
	int Find(int x){
		if(fa[x]==x) return x;
		return fa[x]=Find(fa[x]);
	}
	
	void Merge(int u,int v){
		u=Find(u),v=Find(v);
		if(u==v) return;
		fa[u]=fa[v]; siz[v]+=siz[u];
	}
}D;

signed main(){
	int S; read(S);
	read(n),read(m);
	for(int i=1;i<=m;i++){
		char w[5];
		read(U[i]),read(V[i]);
		scanf("%s",w);
		W[i]=(w[0]=='D')?1:0;
		Add(U[i],V[i]);
		Add(V[i],U[i]);
	}
	num=n; Tarjan(1); dfs1(1,0);
	for(int i=1;i<=m;i++){
		int u=U[i],v=V[i],id;
		if(fa[u]==fa[v]) id=fa[u];
		else if(fa[fa[u]]==v) id=fa[u];
		else id=fa[v];
		s[id].push_back(i);
	}
	ll ans=1ll*n*(n-1)/2;
	for(int i=n+1;i<=num;i++){
		for(int j:s[i]){
			if(W[j]==0) w0[i]=v0[U[j]]=v0[V[j]]=1;
			else w1[i]=v1[U[j]]=v1[V[j]]=1;
		}
		int cnt=0;
		for(int j:e[i]){
			if(v0[j]&&v1[j])
				cnt++;
			v0[j]=v1[j]=0;
		}
		if(cnt==2) ans--;
	}
	D.Init();
	for(int x=1;x<=num;x++){
		for(int t:e[x]){
			if(!w0[x]&&!w0[t])
				D.Merge(x,t);
		}
	}
	for(int i=1;i<=num;i++){
		if(D.Find(i)==i)
			ans-=1ll*D.siz[i]*(D.siz[i]-1)/2;
	}
	D.Init();
	for(int x=1;x<=num;x++){
		for(int t:e[x]){
			if(!w1[x]&&!w1[t])
				D.Merge(x,t);
		}
	}
	for(int i=1;i<=num;i++){
		if(D.Find(i)==i)
			ans-=1ll*D.siz[i]*(D.siz[i]-1)/2;
	}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2025-04-17 18:45  XP3301_Pipi  阅读(44)  评论(0)    收藏  举报
Title