首页 > 其他分享 >Living-Dream 系列笔记 第90期

Living-Dream 系列笔记 第90期

时间:2025-01-14 15:27:45浏览次数:1  
标签:Living return cur idx int vis 90 Dream match

鲜花:其实一直想改一下笔记的形式,以一个算法专题作为一篇博文的内容。这个系列到 100 期就完结吧。

二分图最大独立集

选择最多的点,使得这个点集中的点互相没有连边。

答案显然为 \(n-最小点覆盖=n-最大匹配\)(\(n\) 为总点数)。但是好像最小点覆盖那一期忘记写了,所以解释一下为什么最小点覆盖和最大匹配相等。

首先最小点覆盖就是求一个最小点集能够覆盖所有的边。感性理解一下即可发现,对于无环二分图,我们可以不停地选择一个最大匹配的端点去覆盖从它的端点出发的非最大匹配边,当然最后一条最大匹配边可能需要单独处理;对于偶环,同上,只是无需单独处理。而二分图是没有奇环的,因此我们选择的点即为最大匹配的个数,容易证明这也是最小的(没有浪费)。

P3355

「互不攻击」是一个非常明显的二分图标志。

容易发现骑士总是从一个颜色的格子跳到另一个颜色的格子。考虑将黄色作为左部点,红色作为右部点(反之亦可)。需要注意建图时应排除障碍。

将格子看作点、攻击关系看作边,此题要求放最多的骑士且互不攻击,相当于选最多的点且点之间没有连边,于是求最大独立集即可。

code
#include<bits/stdc++.h>
using namespace std;

const int N=2e2+5;
const int dx[]={2,1,2,-1,1,-2,-1,-2};
const int dy[]={1,2,-1,2,-2,1,-2,-1};
int n,m,tot,tot2;
int idx,ans,match[N*N];
int vis[N*N],p[N][N];
bool yes[N][N];
vector<int> G[N*N];

bool hungary(int cur){
	if(vis[cur]==idx){
		return 0;
	}
	vis[cur]=idx;
	for(int i:G[cur]){
		if(!match[i]||hungary(match[i])){
			match[i]=cur;
			return 1;
		}
	}
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1,x,y;i<=m;i++)
		cin>>x>>y,yes[x][y]=1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			//if(!yes[i][j]){
		        if((i+j)%2==1)
		            p[i][j]=++tot;
		        else
		            p[i][j]=++tot2;
			//}
		}
    }
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if((i+j)%2==0&&!yes[i][j])
				for(int k=0;k<8;k++)
					if(i+dx[k]>=1&&i+dx[k]<=n&&j+dy[k]>=1&&j+dy[k]<=n&&!yes[i+dx[k]][j+dy[k]])
						G[p[i][j]].push_back(p[i+dx[k]][j+dy[k]]);
	for(int i=1;i<=tot2;i++){
		idx++;
		if(hungary(i))
			ans++;
	}
	cout<<n*n-m-ans;
	return 0;
}

P5030

观察可得,长脖子鹿总是奇偶交替地跳(指行),于是将偶数行作为左部点,奇数行作为右部点即可。

然后与上题一模一样了。

这两个题注意方向数组的顺序,应当为右下、左下、右上、左上,调换顺序不会影响正确性,但是先访问没有去过的地方效率会高很多(上面的点被之前匹配的可能性更高)。

P6268

首先肯定男当左部点、女当右部点。

但这题并没有直接告诉你每个学生的性别,于是我们根据题目所给关系染色并重新建图即可。

实际上只需要给出关系的人参与建图即可,其他人直接无脑计入。

code
#include<bits/stdc++.h>
using namespace std;

const int N=3e3+5;
int n,m,tot,tot2;
int idx,ans,match[N];
int vis[N],color[N];
bool yes[N];
vector<int> G[N],T[N];
pair<int,int> e[N];

void fill_it(int cur,int c){
	color[cur]=c;
	for(int i:G[cur])
		if(!color[i])
			fill_it(i,3-c);
}
bool hungary(int cur){
	if(vis[cur]==idx){
		return 0;
	}
	vis[cur]=idx;
	for(int i:T[cur]){
		if(!match[i]||hungary(match[i])){
			match[i]=cur;
			return 1;
		}
	}
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>m;
	for(int i=1,u,v;i<=m;i++){
		cin>>u>>v;
		u++,v++;
		G[u].push_back(v);
		G[v].push_back(u);
		yes[u]=yes[v]=1;
		e[i]={u,v};
	}
	for(int i=1;i<=n;i++)
		if(yes[i]&&!color[i])
			fill_it(i,1);
	for(int i=1;i<=n;i++){
		if(yes[i]){
			for(int j:G[i]){
				if(yes[j]){
					if(color[i]==1)
						T[i].push_back(j);
					else
						T[j].push_back(i);
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(yes[i]&&color[i]==1){
			idx++;
			if(hungary(i))
				ans++;
		}
	}
	cout<<n-ans;
	return 0;
}

UVA12083

和上题一样的套路题,不讲。

code
#include<bits/stdc++.h>
using namespace std;

const int N=5e2+5;
int t,n,idx,ans;
int vis[N],match[N],color[N];
struct STU{
	int h;
	char se;
	string m,sp;
}stu[N];
vector<int> G[N],T[N];

void fillit(int cur,int c){
	color[cur]=c;
	for(int i:G[cur])
		if(!color[i])
			fillit(i,3-c);
}
bool hungary(int cur){
	if(vis[cur]==idx){
		return 0;
	}
	vis[cur]=idx;
	for(int i:T[cur]){
		if(!match[i]||hungary(match[i])){
			match[i]=cur;
			return 1;
		}
	}
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++){
			G[i].clear(),T[i].clear();
			cin>>stu[i].h>>stu[i].se>>stu[i].m>>stu[i].sp;
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<i;j++){
				if(abs(stu[i].h-stu[j].h)<=40&&stu[i].se!=stu[j].se&&stu[i].m==stu[j].m&&stu[i].sp!=stu[j].sp){
					G[i].push_back(j);
					G[j].push_back(i);
				}
			}
		}
		memset(color,0,sizeof color);
		for(int i=1;i<=n;i++)
			if(!color[i])
				fillit(i,1);
		for(int i=1;i<=n;i++){
			for(int j:G[i]){
			    if(color[i]==1)
				    T[i].push_back(j);
				else
					T[j].push_back(i);
			}
		}
		ans=idx=0;
		memset(vis,0,sizeof vis);
		memset(match,0,sizeof match);
		for(int i=1;i<=n;i++){
		    if(color[i]==1){
			    idx++;
			    if(hungary(i))
				    ans++;
		    }
		}
		cout<<n-ans<<'\n';
	}
	return 0;
}

总结:

  • 如何识别二分图模型?最大匹配:最多、不共点;最小点覆盖:至少二选一;最大独立集:最多、不连边。

  • 做二分图的题一般步骤:观察题目标志、确定左 / 右部点、确定边、识别模型、开做。

  • 左 / 右部点无法直接确定时,考虑染色。

  • 仔细观察图或者自己画图,发现性质。

标签:Living,return,cur,idx,int,vis,90,Dream,match
From: https://www.cnblogs.com/XOF-0-0/p/18670792

相关文章

  • 你知道网页三剑客指的是什么吗?你有用过Dreamwear吗?
    网页三剑客指的是一套强大的网页编辑工具,它们分别是Dreamweaver、Fireworks和Flash。这三个软件最初是由美国的Macromedia公司开发出来的,后来被Adobe公司收购。它们各自在网页设计和开发过程中发挥着不同的作用,相互之间能够无缝合作,因此被形象地称为“网页三剑客”。Dreamweave......
  • leetcode2902 和带限制的子多重集合的数目
    给定数组nums[n]和整数l,r,nums中的元素可能会重复,要求从nums中选择若干个元素,其元素和在[l,r]内,有多少种不同方案,结果对1E9+7取模。注:空集合的结果为0,相等的元素之间没有区别。1<=n<=2E4;0<=nums[i]<=2E4;sum(nums[i])<=2E4;0<=l<=r<=2E4分析:1、存在相等元素,且没有区别,可以......
  • Dreamweaver修改织梦网站源码全攻略:从基础操作到高级定制
    Dreamweaver是一款强大的可视化网页编辑工具,非常适合用来修改基于织梦CMS构建的网站源码。以下是几个实用技巧,帮助开发者更高效地完成这项任务:项目结构理解:熟悉织梦网站的整体目录结构,了解各个文件夹和文件的作用。特别是data、include、templets等关键路径下的内容,对于后续开发......
  • 最强卡皇5090登场,游戏玩家吵翻天?
    近日在CES大会上,老黄宣布RTX5090正式发布,价格竟高达16499元!自从显卡被大家熟知后,大家一直对一个话题在网上争论不休,那就是游戏显卡和专业图形显卡之间到底哪个更胜一筹?很多游戏玩家认为,所谓的“专业图像显卡”就是给游戏显卡改了个名,以更高价格去割韭菜;但又有一些用户出来为其正......
  • AcWing算法基础课打卡 | 790 数的三次方根
    学习C++从娃娃抓起!记录下AcWing刷过的题目,记录每一个瞬间。附上汇总贴:AcWing算法基础课打卡|汇总【题目描述】给定一个浮点数,求它的三次方根。【输入】共一行,包含一个浮点数。【输出】共一行,包含一个浮点数,表示问题的解。注意,结果保留位小数。【输入样例】1......
  • 米尔安路DR1M90核心板重磅发布!国产FPGA SoC芯选择
    在边缘智能、物联网、5G通信和自动驾驶等技术的快速发展下,FPGA市场需求呈现爆发式增长。国产FPGA也在这场技术浪潮中崭露头角,吸引了广大行业人士的关注。今天,米尔电子基于安路科技最新一代国产工业级FPGAFPSoC——发布MYC-YM90X SOM模组及评估套件。该产品采用安路飞龙DR1M90,95......
  • SSM“旅迹”旅游网站-毕业设计源码55907
    目 录摘 要1绪论1.1研究背景1.2研究意义1.3论文结构与章节安排2 “旅迹”旅游网站系统分析2.1可行性分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3法律可行性分析2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析2.3 系统用......
  • Azure基础认证(AZ-900)完全指南:(十八)计算的演变 - 专用服务器
    点击进入:Azure基础认证(AZ-900)完全指南(一):认证概述点击进入:Azure基础认证(AZ-900)完全指南(二)考试概述点击进入:Azure基础认证(AZ-900)完全指南:(三)什么是云计算?点击进入:Azure基础认证(AZ-900)完全指南:(四)云服务点击进入:Azure基础认证(AZ-900)完全指南:(五)什么是Azure点击进入:Azure基......
  • Azure基础认证(AZ-900)完全指南:(十九)计算 - 虚拟机的演变
    点击进入:Azure基础认证(AZ-900)完全指南(一):认证概述点击进入:Azure基础认证(AZ-900)完全指南(二)考试概述点击进入:Azure基础认证(AZ-900)完全指南:(三)什么是云计算?点击进入:Azure基础认证(AZ-900)完全指南:(四)云服务点击进入:Azure基础认证(AZ-900)完全指南:(五)什么是Azure点击进入:Azure基......
  • Azure基础认证(AZ-900)完全指南:(二十一)计算的演变 - 函数
    点击进入:Azure基础认证(AZ-900)完全指南(一):认证概述点击进入:Azure基础认证(AZ-900)完全指南(二)考试概述点击进入:Azure基础认证(AZ-900)完全指南:(三)什么是云计算?点击进入:Azure基础认证(AZ-900)完全指南:(四)云服务点击进入:Azure基础认证(AZ-900)完全指南:(五)什么是Azure点击进入:Azure基......