首页 > 其他分享 >qoj5371 Matrix (二分图匹配)

qoj5371 Matrix (二分图匹配)

时间:2024-07-01 20:32:46浏览次数:25  
标签:二分 Matrix int sm2 sm1 qoj5371 long define

qoj5371 Matrix

二分图匹配

判断无解的情况,当且仅当有 \(a_{i,j}\) 为负数或每一行和每一列的和不相同时无解。

因为 \(m\le N^2\),所以我们只需要每一次至少完成一个 \(a_{i,j}\) 即可。观察 \(B\) 矩阵的形成,实际上就是一个 \(i\) 行只能和一个 \(j\) 列匹配,跑二分图匹配即可。每一次求出 \(B\) 矩阵让其系数为其中所有 \(1\) 位置对应的 \(a_{i,j}\) 的最小值,那么对应的 \(a_{i,j}\) 减去系数后会若干位置会变成 \(0\),此时边 \((i,j)\) 无法选择,退掉。重复上面的操作知道二分图最大匹配 \(\ne n\),结束。

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define fi first
#define se second
#define pb push_back

using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
const int N = 60;

int n;
int a[N][N], vis[N], mat[N], sm1[N], sm2[N], p[N];

bool dfs(int u) {
	for (int i = 1; i <= n; i++) {
		if(a[u][i] && !vis[i]) {
			vis[i] = 1;
			if(!mat[i] || dfs(mat[i])) {
				mat[i] = u, p[u] = i;
				return 1;
			}
		}
	}
	return 0;
}
std::vector<std::vector<int> > ans;
void solve() {
	memset(sm1, 0, sizeof(sm1));
	memset(sm2, 0, sizeof(sm2));

	std::cin >> n;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			std::cin >> a[i][j];
			sm1[i] += a[i][j];
			sm2[j] += a[i][j];
		}
	}

	for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (a[i][j] < 0) {
		std::cout << "-1\n";
		return;
	}

	for (int i = 1; i <= n; i++) {                     
		if(sm1[i] != sm1[1] || sm2[i] != sm2[1]) {         
			std::cout << "-1\n";
			return;
		}
	}

	for (int i = 1; i <= n; i++) {
		memset(vis, 0, sizeof(vis));
		dfs(i);
	}

	bool ok = 1;
	while(ok) {
		int mn = iinf;
		for (int i = 1; i <= n; i++) {
			mn = std::min(mn, a[i][p[i]]);
		}
		std::vector<int> v;
		v.pb(mn);
		for (int i = 1; i <= n; i++) {
			a[i][p[i]] -= mn;
			v.pb(p[i]);
		}
		ans.pb(v);
		for (int i = 1; i <= n; i++) {
			if(!a[i][p[i]]) {
				mat[p[i]] = 0, p[i] = 0;
				memset(vis, 0, sizeof(vis));
				if(!dfs(i)) ok = 0; //判断是否仍有增广路
			}
		}
	}

	std::cout << ans.size() << "\n";
	for (int i = 0; i < ans.size(); i++) {
		for (auto x : ans[i]) {
			std::cout << x << " ";
		}
		std::cout << "\n";
	}	
	ans.clear();
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
	int t;
	std::cin >> t;

	while (t--) solve();

	return 0;
}

标签:二分,Matrix,int,sm2,sm1,qoj5371,long,define
From: https://www.cnblogs.com/FireRaku/p/18278780

相关文章

  • 【秋招刷题打卡】Day02-二分系列之-二分查找
    Day02-二分系列之-二分查找前言给大家推荐一下咱们的陪伴打卡小屋知识星球啦,详细介绍=>笔试刷题陪伴小屋-打卡赢价值丰厚奖励<=⏰小屋将在每日上午发放打卡题目,包括:一道该算法的模版题(主要以力扣,牛客,acwing等其他OJ网站的题目作为模版)一道该算法的应用题(主要以往......
  • 二分查找
    二分查找算法思想有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功。一个情景:将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于......
  • 704. 二分查找 27. 移除元素
    704.二分查找题目链接:https://leetcode.cn/problems/binary-search/ 前置条件:数值有序 效果:可以将时间复杂度优化为log(n) 思路:target(可能存在的)元素等于mid位元素时,返回当前下标target元素相对于mid位元素小时,选择左侧区域继续查找t......
  • 代码随想录Day1-二分查找法|快慢指针
    二分查找题目链接二分查找是一个较为基础的查找方式,对一个有序没有重复值的数组进行查找时,能够提供一个较好的时间复杂度\(O(log(n))\)算法概要对于有序并且没有重复值的数组来说,我们可以首先选定整个数组的中间下标,它的值则称为中间值,通过它把大数组分成两个小的数组,其中一个......
  • 【题解】CF1949B | 二分答案 霍尔定理
    本题可以做到低于\(O(n^2)\)。最大化最小值,考虑二分答案\(v\)变为检查可行性:每个主菜匹配的开胃菜的两个值都要在\((-\infty,x-v],[x+v,+\infty]\)间选取,问是否存在主菜与开胃菜的完美匹配。对开胃菜排序,得到第\(i\)个主菜可以匹配到的开胃菜集合为一个后缀和一个前缀:\([......
  • 如何应用 matrix3d 映射变幻
    如何应用matrix3d映射变幻先上demo记得是在2015看到过的一个html5演示效果,很惊艳当时没明白如何实现,现在我会了,做一个类似的:又弄了一个拖动的demo我数学真的很差“你好老师!学这个矩阵具体有什么用?”老师喝着水貌似想了一会儿回答:“考试用”..这个问题我真问过......
  • Vitis HLS 学习笔记--Stream Chain Matrix Multiplication
    目录1.简介2.示例解析2.1示例功能说明2.2函数说明 2.2.1 mmult函数2.2.2 mm2s函数2.2.3 s2mm函数2.2.4总示意图3.总结1.简介这是一个包含使用数据流的级联矩阵乘法的内核。该内核启用了ap_ctrl_chain,以展示如何重叠多个内核调用队列以提供更高的性......
  • Abaqus Matrix Genrate 分析 | 输出总体刚度
    引言abaqus可以输出模型的刚度/质量/阻尼/载荷矩阵等:输出单元刚度矩阵输出范围可以是一个单元,也可以是多个单元输出总体刚度矩阵输出的数据是整个模型的刚度矩阵,或者是某一特定区域的总体刚度矩阵,可以考虑MPC约束,声学等效应.输出总体刚度矩阵abaqus输出总体......
  • java二分查找(对半查找)
    packageday04.Work;publicclassBinary{//使用二分查找//int[]arr={1,3,4,5,6,8,9,12,15,17,26,28,27}privatestaticintchazhao(int[]arr,inti){//左边为leftintleft=0;//右边为数组......
  • 基于K最近邻算法在二分类和回归分析中的应用
    目录前言:案例一、K近邻算法在二分类中的应用1.生成训练集2.用KNN算法拟合这些数据  4.验证KNN算法的分类结果案例二、K近邻算法在多分类中的应用1.生成多分类任务数据集2.用KNN算法拟合这些数据  5.验证KNN算法的分类结果 案例三K近邻算法在回归分析中的应用 1......