首页 > 其他分享 >《一般图最大匹配》学习总结

《一般图最大匹配》学习总结

时间:2023-09-03 22:25:39浏览次数:36  
标签:总结 匹配 vis int tt 学习 mt MAXN return

带花树学不会,不玩了。咕掉。

随机化

来学随机化吧。。。

实际上在随机数据上表现甚至优于带花树,不过他为什么要随机而且为什么随机就能搞我也不知道。

就背一个板子就好了。

点击查看代码
#include<bits/stdc++.h>
typedef long long LL;

using namespace std;
const int MAXN=1e3+10;
int n,m,mt[MAXN];
bool vis[MAXN];
vector<int> e[MAXN];
mt19937 rnd(time(0));
int dfs(int x) {
	shuffle(e[x].begin(),e[x].end(),rnd);
	vis[x]=1;
	for(auto t:e[x]) {
		if(!mt[t]) {
			vis[t]=1; mt[t]=x; mt[x]=t;
			return true;
		}
	}
	for(auto t:e[x]) {
		int tt=mt[t];
		if(vis[tt]) continue;
		mt[x]=t; mt[t]=x; mt[tt]=0;
		if(dfs(tt)) return true;
		mt[t]=tt; mt[tt]=t; mt[x]=0;
	}
	return false;
}
int main () {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i) {
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x);
	}
	double start=clock();
	int ans=0;
	while((double)(clock()-start)/CLOCKS_PER_SEC<=0.80) {
		for(int i=1;i<=n;++i) {
			if(!mt[i]) {
				memset(vis,0,sizeof(vis));
				ans+=dfs(i);
			}
		}
	}
	printf("%d\n",ans);
	for(int i=1;i<=n;++i) printf("%d ",mt[i]);
	return 0;
}

P6113 【模板】一般图最大匹配

模板题

点击查看代码
#include<bits/stdc++.h>
typedef long long LL;

using namespace std;
const int MAXN=1e3+10;
int n,m,mt[MAXN];
bool vis[MAXN];
vector<int> e[MAXN];
mt19937 rnd(time(0));
int dfs(int x) {
	shuffle(e[x].begin(),e[x].end(),rnd);
	vis[x]=1;
	for(auto t:e[x]) {
		if(!mt[t]) {
			vis[t]=1; mt[t]=x; mt[x]=t;
			return true;
		}
	}
	for(auto t:e[x]) {
		int tt=mt[t];
		if(vis[tt]) continue;
		mt[x]=t; mt[t]=x; mt[tt]=0;
		if(dfs(tt)) return true;
		mt[t]=tt; mt[tt]=t; mt[x]=0;
	}
	return false;
}
int main () {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i) {
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x);
	}
	double start=clock();
	int ans=0;
	while((double)(clock()-start)/CLOCKS_PER_SEC<=0.80) {
		for(int i=1;i<=n;++i) {
			if(!mt[i]) {
				memset(vis,0,sizeof(vis));
				ans+=dfs(i);
			}
		}
	}
	printf("%d\n",ans);
	for(int i=1;i<=n;++i) printf("%d ",mt[i]);
	return 0;
}

P4258 [WC2016] 挑战NPC

又是一道人类智慧建模题。

首先直接建肯定是不行。

我们将一个筐拆成 \(3\) 个点。然后三个点之间两两连边,由于题目保证了一定有完美匹配,我们讨论一下筐内小球数量的情况,对于贡献情况:

  • 筐内有没有小球,没有贡献。

  • 筐内有一个小球,贡献为 \(2\) ,这时候多了 \(1\) 的贡献,因为相当于自己是一个没有满半的桶。

  • 筐内有两个小球,贡献为 \(2\) ,这时候自己没有满半,实际贡献为 \(0\) ,所以要减去 \(2\) 的贡献。

  • 筐内有三个小球,要减 \(3\)

这时候我们就可以发现,筐内有多少个小球就要减去多少的贡献。

这样建出模来跑就行了。

点击查看代码
#include<bits/stdc++.h>
typedef long long LL;

using namespace std;
const int MAXN=4010;
int T;
int n,m,E;
int mt[MAXN],vis[MAXN];
vector<int> e[MAXN];
int id(int opt,int x) {
	return n+opt*m+x;
}
void add(int f,int t) {
	e[f].push_back(t);
	e[t].push_back(f);
}
mt19937 rnd(time(0));
bool dfs(int x) {
	shuffle(e[x].begin(),e[x].end(),rnd);
	vis[x]=1;
	for(auto t:e[x]) {
		if(!mt[t]) {
			vis[t]=1; mt[x]=t; mt[t]=x;
			return true;
		}
	}
	for(auto t:e[x]) {
		int tt=mt[t];
		if(vis[tt]) continue;
		mt[x]=t; mt[t]=x; mt[tt]=0;
		if(dfs(tt)) return true;
		mt[x]=0; mt[t]=tt; mt[tt]=t;
	}
	return false;
}
int main () {
	scanf("%d",&T);
	while(T--) {
		scanf("%d%d%d",&n,&m,&E);
		for(int i=1;i<=E;++i) {
			int x,y;
			scanf("%d%d",&x,&y);
			add(x,id(0,y));
			add(x,id(1,y));
			add(x,id(2,y));
		}
		for(int i=1;i<=m;++i) {
			add(id(0,i),id(1,i));
			add(id(0,i),id(2,i));
			add(id(1,i),id(2,i));
		}
		double start=clock();
		int ans=0;
		memset(mt,0,sizeof(mt));
		while(double(clock()-start)/CLOCKS_PER_SEC<=0.15) {
			for(int i=1;i<=n+3*m;++i) {
				if(!mt[i]) {
					memset(vis,0,sizeof(vis));
					ans+=dfs(i);
				}
			}
		}
		printf("%d\n",ans-n);
		for(int i=1;i<=n;++i) {
			printf("%d ",(mt[i]-n-1)%m+1);
		}
		puts("");
		for(int i=1;i<=n+3*m;++i) {
			e[i].clear();
		}
	}
	return 0;
}

标签:总结,匹配,vis,int,tt,学习,mt,MAXN,return
From: https://www.cnblogs.com/ddl1no2home/p/17675717.html

相关文章

  • 代码随想录算法训练营第三十天| 51. N皇后 37. 解数独 总结
        卡哥建议:今天这三道题都非常难,那么这么难的题,为啥一天做三道? 因为 一刷 也不求大家能把这么难的问题解决,所以 大家一刷的时候,就了解一下题目的要求,了解一下解题思路,不求能直接写出代码,先大概熟悉一下这些题,二刷的时候,随着对回溯算法的深入理解,再去解决如下三题。 ......
  • pyspark学习
    frompysparkimport*frompyspark.sqlimportSparkSessionfrompyspark.sqlimportfunctionsasfimportjsonimportosfrompyspark.sql.typesimportStructType,IntegerType,StringType#os.environ['HADOOP_CONF_DIR']='/export/server/h......
  • 《Java编程思想第四版》学习笔记22
    注意下面这两句话:1、针对g()和main(),Throwable类必须在违例规格中出现,因为fillInStackTrace()会生成一个Throwable对象的句柄。由于Throwable是Exception的一个基础类,所以有可能获得一个能够“掷”出的对象(具有Throwable属性),但却并非一个Exception(违例)。因此,在main()......
  • c++单例模式总结
    分类懒汉式:实例对象在第一次被使用时才进行初始化。饿汉式:实例在定义时就被初始化。特点1、构造函数和析构函数私有化,不允许外部创建实例对象。2、拷贝构造函数和复制运算符重载被delete,不允许产生新的实例。3、内部定义一个私有的静态数据成员,该成员为本类的实例化对象。4......
  • STM32深入学习3:GPIO模块控制LED(寄存器版)
    GPIO模块数据手册详解:GPIO:通用输入/输出AFIO:备用输入/输出GPIOx_CRL和GPIOx_CRH:配置寄存器GPIOx_IDR和GPIOx_ODR:数据寄存器GPIOx_BSRR:置位/复位寄存器GPIOx_BRR:复位寄存器GPIOx_LCKR:锁定寄存器,锁定GPIO的数值GPIO模式:1.输入浮动:完全由外部决定2.输入上拉和输入下拉:存在......
  • uniapp项目实践总结(八)自定义加载组件
    有时候一个页面请求接口需要加载很长时间,这时候就需要一个加载页面来告知用户内容正在请求加载中,下面就写一个简单的自定义加载组件。目录准备工作逻辑思路实战演练效果预览准备工作在之前的全局组件目录components下新建一个组件文件夹,命名为q-loading,组件为q-loading......
  • 斜率优化DP 学习笔记
    斜率优化DP适用情况适用于求解最优解(最大、最小)问题。上凸壳与下凸壳求解步骤对于任意状态转义方程,设$A_i$,$B_i$,使状态转移方程转化为$f_i=\min(f_j+(A_i-B_j)^2)$当$i$使从$j$转移来时,丢掉$\min$$f_i=f_j+{A_i}^2+{B_j}^2-2\timesA......
  • 【学习笔记】树套树
    所谓树套树,其本质是通过用树维护一组树的根,从而维护强悍的数据1线段树套平衡树线段树套#include<bits/stdc++.h>usingnamespacestd;#defineMAXN50005intseg[MAXN<<2];intamin=1000000,amax=0;structNode{ intval,rnd,siz; intch[2]; }t[MAXN*80];intt......
  • 聊聊多任务学习
    最近翻译的一篇分享中,主要讲解了多任务学习的各个方面,很多的专业术语与概念都不清楚,因此简单的整理了下相关的知识,做个笔记。概述现在大多数机器学习任务都是单任务学习。对于复杂的问题,也可以分解为简单且相互独立的子问题来单独解决,然后再合并结果,得到最初复杂问题的结果。这......
  • 学习笔记-计算机病毒对抗技术-病毒概述
    本周我们学习下计算机病毒揭秘与对抗技术。主要分为6大模块计算机病毒概念定义计算机病毒(ComputerVirus)指编制者在计算机程序中插入的破坏计算机功能或者破坏数据,影响计算机正常使用并且能够自我复制的一组计算机指令或程序代码。特点1、破坏性2、隐蔽性3、潜伏性4、传染性5、不可......