暗的连锁

https://loj.ac/problem/10131

题目描述

  给出一张图,有\(n\)个节点和两类边,一类为主要边,一类为次要边,主要边构成图的一棵生成树,求有多少种方案可以在断掉一条主要边和一条次要边后与不再连通。

思路

  我们把图看做一棵树,加上一些非树边。我们考虑如果存在一条\(x、y\)的非树边,那么树上\(x、y\)路径上的点一定要斩断这条非树边。所以对于每条非树边\((x,y)\),我们记为把树上\(x、y\)的路径覆盖了一次,由此我们可以知道,对于覆盖了\(0\)次的边,我们斩断它后选任意一条非树边都可以;对于覆盖了\(1\)次的点,我们只有一种方案;对于覆盖了\(2\)次及以上的点,我们无法实现不连通。

  而覆盖了几次这个内容我们可以用树上差分实现,由于边不好记录,我们先转化为点,对于\((x,y)\),使用树上差分,我们把\(val[x]++,val[y]++,val[lca]-2\)实现,最后每个点的实际值就是其子树的权值和。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;

int nxt[N<<1],to[N<<1],from[N<<1],tot,head[N];
void add_edge(int x,int y)
{
	nxt[++tot]=head[x];
	head[x]=tot;
	to[tot]=y;from[tot]=x;
}

int f[N][22],dep[N];
void deal_first(int u,int fa)
{
	dep[u]=dep[fa]+1;
	for(int i=0;i<20;i++)
		f[u][i+1]=f[f[u][i]][i];
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];
		if(v==fa)continue ;
		f[v][0]=u;
		deal_first(v,u);
	}
}
int LCA(int x,int y)
{
	if(dep[x]<dep[y])swap(x,y);
	for(int i=20;i>=0;i--)
	{
		if(dep[f[x][i]]>=dep[y])x=f[x][i];
		if(x==y)return y;
	}
	for(int i=20;i>=0;i--)
		if(f[x][i]!=f[y][i])
		{
			x=f[x][i];
			y=f[y][i];
		}
	return f[x][0];
}
int sum[N],val[N];
void dfs(int u,int fa)
{
	sum[u]=val[u];
	for(int i=head[u];i;i=nxt[i])
	{
		int v=to[i];
		if(v==fa)continue ;
		dfs(v,u);
		sum[u]+=sum[v];
	}
}

int read()
{
	int res=0,w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
	return res*w;
}
void write(int x)
{
	if(x<0){putchar('-');x=-x;}
	if(x>9)write(x/10);
	putchar(x%10+'0');
} 
void writeln(int x)
{
	write(x);
	putchar('\n');
}

int main() 
{
	int n=read(),m=read();
	for(int i=1;i<n;i++)
	{
		int x=read(),y=read();
		add_edge(x,y);add_edge(y,x);
	}
	deal_first(1,0);
	for(int i=1;i<=m;i++)
	{
		int x=read(),y=read();
		int lca=LCA(x,y);
		val[x]++;val[y]++;
		val[lca]-=2;
	}
	dfs(1,0);
	int ans=0;
	for(int i=2;i<=n;i++)
		if(sum[i]==1)ans++;
		else if(sum[i]==0)ans+=m;
	writeln(ans);
	return 0;
}

posted @ 2019-11-03 18:42  fbz  阅读(119)  评论(0编辑  收藏  举报