首页 > 其他分享 >【XSY4182】下一个(next)(欧拉回路,构造)

【XSY4182】下一个(next)(欧拉回路,构造)

时间:2022-10-31 07:36:11浏览次数:38  
标签:XSY4182 度数 ch 每个 int next 偶数 欧拉 deg

题面

下一个(next)

题解

我们可以这么转化问题:给每一条边定向,使得每一个点的出度至少为 \(2\)。

证明新问题是原问题的充分条件:定好向后,我们先给每个点随便选一条出边,显然这些边形成若干连通块,且每个连通块点数不大于边数(都是基环树),且每个点都被恰好覆盖一次。然后我们把这些边删去,让剩下的边形成若干连通块,由新问题构造条件可知现在每个点肯定至少有一条出边被选上,于是能保证这些连通块中每个连通块点数不大于边数(都是基环树),且每个点都恰好又被恰好覆盖一次。

如何找呢,每个点度数至少为 \(4\) 是一个很关键的信息。我们先把原图建出来,并设置一个虚点 \(S\),对于每一个点,如果它的度数为奇数,那么我们就将它和 \(S\) 连一条边。这样每个节点度数都是偶数(可以这么理解,一条边贡献两个度数所以总度数一定是偶数,而除了 \(S\) 以外的所有点的度数都是偶数了,所以 \(S\) 的度数也是偶数)。

然后我们跑欧拉回路,然后直接按欧拉回路的方向定向即可。原因:对于每个点 \(u\),设 \(deg_u\) 为 \(u\) 在原图上的度数(没加虚边前的)。若 \(deg_u\) 为偶数,那么它的出度为 \(\frac{deg_u}{2}\geq 2\),满足;若 \(deg_u\) 为奇数,那么我们新连了一条虚边,它的出度至少为 \(\frac{deg_u+1}{2}-1\geq 2\),满足。

#include<bits/stdc++.h>

#define N 500010
#define M 1000010

using namespace std;

inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^'0');
		ch=getchar();
	}
	return x*f;
}

struct Edge
{
	int u,v;
};

struct data
{
	int v,id;
	data(){};
	data(int a,int b){v=a,id=b;}
};

const int E=(N+M)<<1;

int n,m,S;
int cnt=1,head[N],nxt[E],to[E];
bool vis[N],dir[E];
int deg[N];
int fa[N];
int tot,num[N];
int ans[M];

vector<data>e[N];

void adde(int u,int v)
{
	to[++cnt]=v;
	nxt[cnt]=head[u];
	head[u]=cnt; 
}

void dfs(int u)
{
	vis[u]=1;
	for(int &i=head[u];i;i=nxt[i])
	{
		if(dir[i]||dir[i^1]) continue;
		int v=to[i];
		dir[i]=1;
		dfs(v);
	}
}

int find(int x)
{
	return x==fa[x]?x:(fa[x]=find(fa[x]));
}

void merge(int u,int v)
{
	int a=find(u),b=find(v);
	if(a!=b) fa[a]=b;
}

int main()
{
	n=read(),m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		deg[u]++,deg[v]++;
		adde(u,v),adde(v,u);
	}
	S=n+1;
	for(int i=1;i<=n;i++)
		if(deg[i]&1) adde(i,S),adde(S,i);
	for(int i=1;i<=n;i++)
		if(!vis[i]) dfs(i);
	for(int i=2;i<=cnt;i++)
	{
		if(dir[i])
		{
			int u=to[i^1],v=to[i];
			if(u!=S&&v!=S) e[u].push_back(data(v,i/2));
		}
	}
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int u=1;u<=n;u++)
	{
		int v=e[u][0].v;
		merge(u,v);
	}
	for(int i=1;i<=n;i++)
		if(fa[i]==i) num[i]=++tot;
	for(int u=1;u<=n;u++)
		ans[e[u][0].id]=num[find(u)];
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int u=1;u<=n;u++)
		for(int i=1,size=e[u].size();i<size;i++)
			merge(u,e[u][i].v);
	for(int i=1;i<=n;i++)
		if(fa[i]==i) num[i]=++tot;
	for(int u=1;u<=n;u++)
		for(int i=1,size=e[u].size();i<size;i++)
			ans[e[u][i].id]=num[find(u)];
	printf("1\n%d\n",tot);
	for(int i=1;i<=m;i++)
		printf("%d ",ans[i]);
	return 0;
}
/*
5 10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
*/

标签:XSY4182,度数,ch,每个,int,next,偶数,欧拉,deg
From: https://www.cnblogs.com/ez-lcw/p/16842966.html

相关文章

  • 【XSY3588】B(图论,欧拉回路)
    题意:给一张\(n\)个点\(m\)条边的简单连通无向图,保证\(m\)为偶数。可知度数为奇数的点共有偶数个,你需要将它们两两分组,对于每一组点\(u,v\),你要找到一条包含偶数条边......
  • 【bzoj4869】【六省联考2017】相逢是问候(扩展欧拉函数)
    和《花神游历各国》有异曲同工之妙。首先能想到扩展欧拉定理:\[a^b\equiv\begin{cases}a^{b\bmod\varphi(p)+\varphi(p)}&\text{if}b\geq\varphi(p)\\a^b&\text{if}......
  • 一文了解 NextJS 并对性能优化做出最佳实践
    引言从本文中,我将从是什么,为什么,怎么做来为大家阐述NextJS以及如何优化NextJS应用体验。一、NextJS是什么NextJS是一款基于React进行web应用开发的框架,它以极......
  • 久违了!欧拉函数
    GCD-HDU2588-VirtualJudge(vjudge.net)题意:给定n,m,n<=1e9for(inti=1;i<=n;i++){if(gcd(i,n)>=m)cnt++;}注意到n<=1e9,这个模拟算法是不能通过的如......
  • 数论-欧拉函数 学习笔记
    一、欧拉函数1.欧拉函数的定义欧拉函数(Euler’stotientfunction),即,表示的是小于等于和比如说。当n是质数的时候,显然有。2.欧拉函数的一些性质欧拉函数是积性函数。......
  • Hexo Next主题vercel页面NOT_FOUND
    前端时间将博客部署到了Vercel上,使用的是HexoNext主题。发现某些博文点进去以后会出现找不到的情况:404:NOT_FOUNDCode:NOT_FOUNDID:......经过一番排查,原来是因......
  • 图论----欧拉路径与欧拉回路
    好博客:https://www.acwing.com/solution/content/53434/https://ycw123.blog.luogu.org/ou-la-hui-lu-yu-ou-la-lu-jing《介绍与性质》      对于无向图来......
  • STL函数之全排列next_permutation
    题目描述牛牛的作业薄上有一个长度为n的排列A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过10个)看不清了,但是牛牛记得这个数列顺序对的数量是k,顺......
  • JavaScriptDOM节点操作:parentNode、children、nextElementSibling、previousElementS
    元素.parentNode:获取元素的最近一级父级节点父元素.children:获取所有子元素元素.nextElementSibling:获取元素的下一个同级元素元素.previousElementSibling:获取元素的上......
  • 欧拉降幂
    放一张看烂的图欧拉降幂就是第一个和第三个公式了,第二种情况直接快速幂算当与模数互质时,当与模数不互质时,,这也就是广义欧拉定理适用于幂次很大时,可以有效降低复杂度在......