首页 > 编程语言 >【图论】最大势算法

【图论】最大势算法

时间:2023-12-30 21:44:50浏览次数:44  
标签:mini 图论 最大 int pot back vis 算法 maxn

模板题Fishing Net

给定一个无向图,判断是否是弦图。

\(1 \leq n \leq 1000\)。

算法概述

最大势算法(MCS),是一个用于求出无向图完美消除序列的算法。算法流程为:

  • 钦定一个集合 \(S\) 。

  • 每次找到任意一个与 \(S\) 中的点连边最多的点,加入 \(S\) ,放在消除序列末尾。

这样就可以 \(\Theta(n + m)\) 求出这个序列,具体实现以连边数为下标开一个桶即可。

这个如何用于弦图判断呢?

有一些概念:

  • 导出子图:一些点集,边被选入当且仅当两个端点都被选入。

  • 单纯点:设一个点集 \(X\) 为一个点以及与它相邻的点, \(X\) 的导出子图是完全图,那么这个点就是单纯点。

有定理:

图是弦图的充要条件是, \(\forall i \in [1,n]\) ,\(a_i\) 是 \(a_{[i,n]}\) 导出子图的单纯点。

不会证

这样,判断这个序列满足这个性质就好了。

从左到右检查每一位,设集合 \(X\) 是 \(a_{[i,n]}\) 中与 \(a_i\) 相邻的点,那么看 \(X\) 是否是完全图即可。

不太好判,又发现设 \(a_j\) 是 \(a_i\) 后第一个与 \(a_i\) 连边的点,那么 \(a_j\) 也会被检查一遍,这个过程是迭代的,只需要检查 \(a_j\) 与后面连接 \(a_i\) 的点是否有连边即可。

复杂度 \(\Theta(n + m)\) 。

#include<bits/stdc++.h>
using namespace std;
const int N = 2005;
vector <int> G[N];
int n,m,seq[N];
inline void MCS()
{
	static int vis[N],lab[N];
	static vector <int> pot[N];
	fill(lab,lab + n + 1,0);
	fill(vis,vis + n + 1,0); 
	for(int i = 0;i <= n;i++) pot[i].clear();
	for(int i = 1;i <= n;i++) pot[0].push_back(i);
	for(int i = n,maxn = 0;i >= 1;i--)
	{
		int flag = 0,cur;
		while(flag == 0)
		{
			while(pot[maxn].size() && vis[pot[maxn].back()]) pot[maxn].pop_back();
			if(!pot[maxn].size()) maxn--;
			else cur = pot[maxn].back(),flag = 1;
		}
		seq[i] = cur; vis[cur] = 1;
		for(auto to : G[cur])
		{
			if(vis[to]) continue;
			lab[to]++;
			pot[lab[to]].push_back(to);
			maxn = max(maxn,lab[to]);
		}
	}
}
inline bool judge()
{
	static int pos[N],vis[N];
	fill(vis,vis + n + 1,0);
	for(int i = 1;i <= n;i++) pos[seq[i]] = i;
	for(int i = 1;i <= n;i++)
	{
		int mini = n + 1;
		for(auto to : G[i]) 
			if(pos[to] > pos[i]) 
				if(mini == n + 1 || pos[to] < pos[mini])
					mini = to;
		if(mini == n + 1) continue;
		for(auto to : G[mini]) vis[to] = 1;
		for(auto to : G[i])
			if(pos[to] > pos[i] && to != mini)
				if(vis[to] == 0)
					return false;
		for(auto to : G[mini]) vis[to] = 0;
	}
	return true;
}
int main()
{
	cin>>n>>m;
	while(n > 0 && m > 0)
	{
		for(int i = 1;i <= n;i++) G[i].clear();	
		for(int i = 1,x,y;i <= m;i++)
		{
			cin>>x>>y;
			G[x].push_back(y);
			G[y].push_back(x);
		}
		MCS();
		puts(judge() ? "Perfect" : "Imperfect");
		cin>>n>>m;
	}
	return 0;
}

那么这个序列的简单应用?

[HNOI2008] 神奇的国度

求弦图的色数。

弦图的性质:团数等于色数。

如果只求数量直接对每个 \(i\) 判断 \(|X_i + 1|\) 即可,如果染色就在序列上从后往前贪心染。

[TJOI2007] 小朋友

求弦图最大独立集。

从前往后跑,我们发现选了这个点,后面相邻的就不能选,贪心即可。

考虑每个团一定只有一个点被选入,所以我们尽量不影响其他的团选点,发现对于第一个所属的一个团而言,这个团里一定有第一个点的所有相邻点。所以选完第一个点后不会影响到其他的团。

标签:mini,图论,最大,int,pot,back,vis,算法,maxn
From: https://www.cnblogs.com/TheLastCandy/p/17936862

相关文章

  • 限流算法
    计数器在固定时间间隔内,处理请求有上限,请求超出部分丢弃。packagemainimport( "sync" "time" klog"k8s.io/klog/v2")typecounterRateLimiterstruct{ msync.Mutex startPartTimeint64 endPartTimeint64 maxCountint currCou......
  • 图论1
    A.能量树时间限制:1000ms空间限制:262144kB题目描述时间:1s空间:256M题目描述:小信有 n 个节点的有根能量树,根为 1。最开始,树上每个节点的能量都是 0。现在小信有 n 个能量球,第 i 个能量球拥有 vi​ 能量。她想把这 n 个能量球分别放置在能量树......
  • 图论
    相关定义图是一个二元组\((V,E)\),节点集合为\(V\),边集合为\(E\),其中边\((u,v)\)的顶点为\(u,v\)。其中顶点的度数为以该顶点为端点的边数。有向图:每条边存在一个方向\(u\)->\(v\),对于有向图,点\(u\)的出度为从\(u\)出发的边数,入度为到\(u\)的边数。无向图:每条......
  • DES加密算法优缺点大揭秘:为何它逐渐被取代?
    一、引言DES(DataEncryptionStandard)加密算法作为一种历史悠久的对称加密算法,自1972年由美国国家标准局(NBS)发布以来,广泛应用于各种数据安全场景。本文将从算法原理、优缺点及替代方案等方面,对DES加密算法进行全面解析。DES加密解密|一个覆盖广泛主题工具的高效在线平台(......
  • 垃圾回收算法-通用的分代垃圾回收机制
    垃圾回收算法-通用的分代垃圾回收机制  概要  分代垃圾回收机制,是基于这样一个事实:不同对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率。  我们将对象分为三种状态:年轻代、年老代、永久代。同时,将处于不同状态的对象放......
  • 二分查找算法---java----黑马程序员算法
    1.二分查找算法给定的条件:给定的有序数组A查找目标值为target,其中A标记为 数组序号从0开始,其下标最大为数组长度-1.举例数组:5  14  22 30 31  41 44条件:i>j  i表示左边下标   j表示右边下标   i从5开始   j 从44开始思想:每次计算其......
  • AVR智能充电器PID算法程序
    资源文件列表AVR智能充电器PID算法程序/battery_charge.prj , 3596AVR智能充电器PID算法程序/battery_charge.pr~ , 3579AVR智能充电器PID算法程序/battery_charge.txt , 0AVR智能充电器PID算法程序/main.asm , 17395AVR智能充电器PID算法程序/main.c , 6285AVR智能充......
  • 08fdma数据通路加入sobel算法IP方案
    软件版本:vitis2021.1(vivado2021.1)操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录"米联客"FPGA社区-www.uisrc.com视频课程、答疑解惑!8.1概述    本文实验目的:1:掌握2个uifdma_dbufIP的同时使用,以及读写通道之间的同步设计2:实现1路数据实时显示......
  • 算法学习Day17二叉树迭迭迭迭代
    Day17迭迭迭迭代ByHQWQF2023/12/28笔记110.平衡二叉树给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树_每个节点_的左右两个子树的高度差的绝对值不超过1。示例1:输入:root=[3,9,20,null,null,15,7]输出:true递归法......
  • 代码随想录算法训练营第十七天 | 110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和
    一、110.平衡二叉树题目链接:LeetCode110.平衡二叉树学习:思路:后序遍历。实际上是由叶结点到根结点,若有一颗子树不是平衡二叉树,则直接返回给根结点二、257.二叉树的所有路径题目链接:LeetCode257.二叉树的所有路径学习:思路:递归+回溯。因为是线=先遍历根结点,然后遍历左孩......