首页 > 其他分享 >CF1707C DFS Trees

CF1707C DFS Trees

时间:2022-10-13 13:33:06浏览次数:70  
标签:遍历 fa int DFS CF1707C 返祖 edge Trees 节点

观察伪代码,对于每个节点总是走未走过且边权最小的边 。

首先我们要先求出求出最小生成树 \(G\)。

非最小生成树的边分为返祖边和横叉边。

接下来,分类讨论 :

设非树边的两个节点为 \(x,y\),根据最小生成树的性质,可以得到非树边的权值 \(edge(x,y)\) 大于 \(x,y\) 在图 \(G\) 的路径上所有边的权值。

1.返祖边

以此图为例:

\(4\) 到 \(1\) 的返祖边的权值一定大于 \(edge(2,4),edge(2,1)\) 。

从 \(2\) 开始遍历,先走 \(edge(1,2)\) 这条边,遍历完子树 \(5\) 后回溯到节点 \(1\),走 \(edge(1,4)\),显然形成的兔变为最小生成树。

从 \(4\) 开始遍历,先走 \(edge(2,4),edge(2,1)\),遍历完子树 \(5\) 后回溯到节点 \(1\),不会走 \(edge(1,4)\)。

从 \(4\) 的子树的任意一个节点开始遍历, 一定先到 \(4\) 然后按上一种方式遍历,从 \(1\) 的其他子树开始遍历同理。

所以在 \(x,y\) 在图 \(G\) 的路径上的所有节点(不含 \(x,y\))不能容纳这条返祖边 \(edge(x,y)\)。

  1. 横叉边

以此图为例:

证明的方法与返祖边类似,所以直接说结论: 所有非 \(x\) 或 \(y\) 子树的所有节点都不能容纳这条横叉边 \(edge(x,y)\)。

\(Code\)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+1;
int n,m,tot,num;
int fa[N];
int dep[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
vector < int > to[N];//树边
vector < pair < int , int > > ex;//非树边对,分为返祖边与横叉边
vector < int > exto[N];
void find_dep(int x,int fa)
{
	dep[x]=dep[fa]+1;
	for(int i=0; i<to[x].size(); i++)
	{
		static int y;
		y=to[x][i];
		if(y==fa)continue;
		find_dep(y,x);
	}
	return;
}
int vis[N];
int now[N];
int could[N];
void find_exto(int x,int fa)
{
	now[dep[x]]=x;
	for(int i=0; i<exto[x].size(); i++)
	{
		static int y;
		y=exto[x][i];
		if(now[dep[y]]==y)
		{
			could[1]++;
			could[now[dep[y]+1]]--;
			could[x]++;
		}
		else
		{
			could[x]++;
			could[y]++;
		}
	}
	for(int i=0; i<to[x].size(); i++)
	{
		if(to[x][i]==fa)continue;
		find_exto(to[x][i],x);
	}
}
void find_add(int x,int fa)
{
	could[x]+=could[fa];
	for(int i=0; i<to[x].size(); i++)
	{
		static int y;
		y=to[x][i];
		if(y==fa)continue;
		find_add(y,x);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++)fa[i]=i;
	for(int i=1; i<=m; i++)
	{
		static int x,y;
		scanf("%d%d",&x,&y);
		int fx=find(x),fy=find(y);
		if(fx!=fy)
		{
			fa[fx]=fy;
			to[x].push_back(y);
			to[y].push_back(x); 
		}
		else
		{
			tot++;
			ex.push_back(make_pair(x,y));
		}
	}
	find_dep(1,0);
	for(int i=0; i<ex.size(); i++)
	{
		static int x,y;
		x=ex[i].first;
		y=ex[i].second;
		if(dep[x]<dep[y])swap( x,y );
		exto[x].push_back(y);
	}
	find_exto(1,0);
	find_add(1,0);
	for(int i=1; i<=n; i++)cout<<(could[i]==tot);
}

标签:遍历,fa,int,DFS,CF1707C,返祖,edge,Trees,节点
From: https://www.cnblogs.com/dadidididi/p/16787879.html

相关文章

  • FastDfs操作
    FastDfs安装准备libfastcommon-1.0.48.tar.gzfastdfs-6.07.tar.gzlibfastcommon-1.0.48.tar.gzfastdfs-6.07.tar.gz安装gcc环境yuminstall-ygccgcc-c++开始......
  • HDFS、Ceph、GFS、GPFS、Swift、Lustre……容器云选择哪种分布式存储更好?
    HDFS、Ceph、GFS、GPFS、Swift、Lustre……容器云选择哪种分布式存储更好?-51CTO.COM   容器云在使用分布式存储时,HDFS、CEPH、GFS、GPFS、Swift等分布式存储哪种更......
  • (转)使用Sqoop导入数据到HDFS及一些设置
    原文:https://www.cnblogs.com/weiyiming007/p/10820932.html一、导数据1、import和exportSqoop可以在HDFS/Hive和关系型数据库之间进行数据的导入导出,其中主要使用了i......
  • FastDFS
    一、FastDFS简介FastDFS是一个轻量级的开源分布式文件系统,纯C实现,所以在Linux中部署时要引入C语言包主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载......
  • 注意使用 ImageSharp 或其关联套件 NPOI、PdfSharpCore、ABP 等,现在要收费了
    注意是否使用ImageSharp套件,从2022-7-15开始要收费了,将影响许多工具,如使用NPOI、PdfSharpCore、ABP的用户也要收费。免费使用条件:您正在将作品用于在开源或可用......
  • Codeforces Round #170 (Div. 1) A. Learning Languages(连通块+dfs)
    https://codeforces.com/contest/277/problem/A题目大意:有n个人,有m种语言;这n个人分别会一些(也有可能会0种);问我们他们能否直接或者间接的交流?如果不能的话,一个人去......
  • 「CF917D」Stranger Trees
    题目点这里看题目。给定一棵包含\(n\)个结点的树\(T\)。对于\(x\in[0,n-1]\cap\mathbbZ\),求与\(T\)恰好有\(x\)条边相同的树的有标号无根树个数。对\(10^9+......
  • hashset和treeset
    因为都是set的子类,Set具有元素不可重复性,所以TreeSet和hashset都不可放2个相同的元素TreeSet底层是TreeMap实现的,很多api都是利用TreeMap来实现的HashSet底层是HashMap......
  • Bob's Problem - trees, greedy
    Bobwasintrouble.Herubbedthemagicringonhisfinger,andyoucameoutoftheground.Youaregivenanundirectedgraph GG whichcontains nn vertices......
  • 实现fastdfs防盗链功能
    目录1、背景2、实现原理2.1开启防盗链2.2重启nginx2.3Java代码生成token1、token生成规则2、java生成token3、测试3.1带正确token访问3.2带错误token访问4、项目代码......