图论练习5

Going Home

Here

解题思路

  • KM模板 
  • 二分图最优匹配,前提是有完美匹配(即存在一一配对)
  • 左右集合分别有顶标lx[i],ly[j],当lx[i]+ly[j]=w[i][j]时,i\rightarrow j为有效边,即选中
  • 初始lx[i]=-inf,ly[j]=0
  • 对于左集合每个点,选择其连边中最优的,lx[i]=Max\ w
  • 然后对于每个点找其最优匹配
  • 若能在前面连好边的图中找到匹配,则继续下一个点
  • 若不能,考虑撤销边
  • 如何撤销?
  • 对于这次找增广路左集合中的点,找一条不在这条增广路上的边,进行替换
  • 找到最小代价,即d=Min\ lx[i]+ly[j]-w[i][j]
  • 对于这次找增广路访问到的左集合lx[i]-d,右集合ly[j]+d
  • 重复进行,直到实现该点找到增广路可以添入或不能进行替换(无完美匹配)
  • 对于该题,求最小,只用将距离变为负值,最后结果在反回来
  • 每次找增广路前清空visx[],viy[]

import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;//implements Runnable
public class Main{static long md=(long)998244353;static long Linf=Long.MAX_VALUE/2;static int inf=Integer.MAX_VALUE/2;static int N=200;staticclass Node{int x;int y;public Node(int u,int v) {x=u;y=v;}}static int[][] w=new int[N+1][N+1];static void getw(Node a,Node b,int i,int j) {w[i][j]=-(Math.abs(a.x-b.x)+Math.abs(a.y-b.y));}static int mm=0;static int hh=0;static int[] lx=new int[N+1];static int[] ly=new int[N+1];static int[] link=new int[N+1];static boolean[] visx=new boolean[N+1];static boolean[] visy=new boolean[N+1];static Node[] men=new Node[N+1];static Node[] home=new Node[N+1];static boolean dfs(int x) {visx[x]=true;for(int i=1;i<=hh;++i) {if(!visy[i]&&lx[x]+ly[i]==w[x][i]) {visy[i]=true;if(link[i]==0||dfs(link[i])) {link[i]=x;return true;}}}return false;}static void solve() throws Exception{AReader input=new AReader();PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));	while(true) {int n=input.nextInt();int m=input.nextInt();if(n==0&&m==0)break;mm=0;hh=0;Arrays.fill(link, 0);for(int i=1;i<=n;++i) {String string=" "+input.next();char[] mp=string.toCharArray();for(int j=1;j<mp.length;++j) {if(mp[j]=='m') {mm++;men[mm]=new Node(i, j);}else if(mp[j]=='H') {hh++;home[hh]=new Node(i, j);}}}for(int i=1;i<=mm;++i){for(int j=1;j<=hh;++j) {getw(men[i], home[j], i, j);}}for(int i=1;i<=mm;++i) {lx[i]=-inf;for(int j=1;j<=hh;++j) {ly[j]=0;lx[i]=Math.max(lx[i], w[i][j]);}}boolean ok=true;for(int i=1;i<=mm;++i) {while(true) {//对于当前点i找个匹配,一直试Arrays.fill(visx, false);Arrays.fill(visy, false);int dis=inf;if(dfs(i))break;//直接不能找到//考虑改边for(int j=1;j<=mm;++j) {if(!visx[j]) continue;for(int k=1;k<=hh;++k) {if(visy[k])continue;dis=Math.min(dis, (lx[j]+ly[k])-w[j][k]);}}if(dis==inf) {ok=false;break;}for(int j=1;j<=mm;++j)if(visx[j])lx[j]-=dis;for(int j=1;j<=hh;++j)if(visy[j])ly[j]+=dis;}if(!ok)break;}int sum=0;if(ok) {for(int i=1;i<=hh;++i) {sum-=w[link[i]][i];}out.println(sum);}else out.println(-1);}out.flush();out.close();}public static void main(String[] args) throws Exception{solve();}
//	public static final void main(String[] args) throws Exception {
//		  new Thread(null, new Main(), "线程名字", 1 << 27).start();
//	}
//		@Override
//		public void run() {
//			try {
//				//原本main函数的内容
//				solve();
//
//			} catch (Exception e) {
//			}
//		}staticclass AReader{ BufferedReader bf;StringTokenizer st;BufferedWriter bw;public AReader(){bf=new BufferedReader(new InputStreamReader(System.in));st=new StringTokenizer("");bw=new BufferedWriter(new OutputStreamWriter(System.out));}public String nextLine() throws IOException{return bf.readLine();}public String next() throws IOException{while(!st.hasMoreTokens()){st=new StringTokenizer(bf.readLine());}return st.nextToken();}public char nextChar() throws IOException{//确定下一个token只有一个字符的时候再用return next().charAt(0);}public int nextInt() throws IOException{return Integer.parseInt(next());}public long nextLong() throws IOException{return Long.parseLong(next());}public double nextDouble() throws IOException{return Double.parseDouble(next());}public float nextFloat() throws IOException{return Float.parseFloat(next());}public byte nextByte() throws IOException{return Byte.parseByte(next());}public short nextShort() throws IOException{return Short.parseShort(next());}public BigInteger nextBigInteger() throws IOException{return new BigInteger(next());}public void println() throws IOException {bw.newLine();}public void println(int[] arr) throws IOException{for (int value : arr) {bw.write(value + " ");}println();}public void println(int l, int r, int[] arr) throws IOException{for (int i = l; i <= r; i ++) {bw.write(arr[i] + " ");}println();}public void println(int a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(int a) throws IOException{bw.write(String.valueOf(a));}public void println(String a) throws IOException{bw.write(a);bw.newLine();}public void print(String a) throws IOException{bw.write(a);}public void println(long a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(long a) throws IOException{bw.write(String.valueOf(a));}public void println(double a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(double a) throws IOException{bw.write(String.valueOf(a));}public void print(char a) throws IOException{bw.write(String.valueOf(a));}public void println(char a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}}}

poj3041 Asteroids

Here

解题思路

  • 对于一个陨石(i,j),可以选择打第i行或第j列,一定只选其中一个
  • 考虑二分图匹配
  • 左集合为所有行,右集合为所有列,每个陨石看作行列的一条连边
  • 所以打完陨石的最少次数,即选择最少的点实现对所有边覆盖
  • 即求最小点覆盖,也就是最大匹配(最小点覆盖等于最大匹配)

import java.io.*;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;//implements Runnable
public class Main{static long md=(long)998244353;static long Linf=Long.MAX_VALUE/2;static int inf=Integer.MAX_VALUE/2;static int N=501;static int n=0;static int k=0;static boolean[][] w=new boolean[N+1][N+1];static boolean[] visy=new boolean[N+1];static int[] link=new int[N+1];static boolean dfs(int x) {for(int i=1;i<=n;++i) {if(!visy[i]&&w[x][i]) {visy[i]=true;if(link[i]==0||dfs(link[i])) {link[i]=x;return true;}}}return false;}static void solve() throws Exception{AReader input=new AReader();PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));	n=input.nextInt();k=input.nextInt();for(int i=1;i<=k;++i) {int x=input.nextInt();int y=input.nextInt();w[x][y]=true;}int sum=0;for(int i=1;i<=n;++i) {Arrays.fill(visy, false);if(dfs(i))sum++;}out.print(sum);out.flush();out.close();}public static void main(String[] args) throws Exception{solve();}
//	public static final void main(String[] args) throws Exception {
//		  new Thread(null, new Main(), "线程名字", 1 << 27).start();
//	}
//		@Override
//		public void run() {
//			try {
//				//原本main函数的内容
//				solve();
//
//			} catch (Exception e) {
//			}
//		}staticclass AReader{ BufferedReader bf;StringTokenizer st;BufferedWriter bw;public AReader(){bf=new BufferedReader(new InputStreamReader(System.in));st=new StringTokenizer("");bw=new BufferedWriter(new OutputStreamWriter(System.out));}public String nextLine() throws IOException{return bf.readLine();}public String next() throws IOException{while(!st.hasMoreTokens()){st=new StringTokenizer(bf.readLine());}return st.nextToken();}public char nextChar() throws IOException{//确定下一个token只有一个字符的时候再用return next().charAt(0);}public int nextInt() throws IOException{return Integer.parseInt(next());}public long nextLong() throws IOException{return Long.parseLong(next());}public double nextDouble() throws IOException{return Double.parseDouble(next());}public float nextFloat() throws IOException{return Float.parseFloat(next());}public byte nextByte() throws IOException{return Byte.parseByte(next());}public short nextShort() throws IOException{return Short.parseShort(next());}public BigInteger nextBigInteger() throws IOException{return new BigInteger(next());}public void println() throws IOException {bw.newLine();}public void println(int[] arr) throws IOException{for (int value : arr) {bw.write(value + " ");}println();}public void println(int l, int r, int[] arr) throws IOException{for (int i = l; i <= r; i ++) {bw.write(arr[i] + " ");}println();}public void println(int a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(int a) throws IOException{bw.write(String.valueOf(a));}public void println(String a) throws IOException{bw.write(a);bw.newLine();}public void print(String a) throws IOException{bw.write(a);}public void println(long a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(long a) throws IOException{bw.write(String.valueOf(a));}public void println(double a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}public void print(double a) throws IOException{bw.write(String.valueOf(a));}public void print(char a) throws IOException{bw.write(String.valueOf(a));}public void println(char a) throws IOException{bw.write(String.valueOf(a));bw.newLine();}}}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/726487.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sqli-labs靶场第18关详解[Sqli-labs-less-18]自动化注入-SQLmap工具注入

Sqli-labs-Less-18 通过测试发现&#xff0c;在登录界面没有注入点&#xff0c;通过已知账号密码admin&#xff0c;admin进行登录发现&#xff1a; 返回了User Agent&#xff0c;设想如果在User Agent尝试加上注入语句&#xff08;报错注入&#xff09;&#xff0c;测试是否会…

react hooks useReducer使用

在React中&#xff0c;useReducer是一个用于管理组件状态的Hook&#xff0c;它特别适用于处理复杂的状态逻辑和多个相关状态。这个Hook接收一个reducer函数&#xff08;与Redux中的reducer概念类似&#xff09;和一个初始状态作为参数&#xff0c;并返回一个新的state值以及一个…

Unity中关于继承ScriptableObject的类

在游戏中我们会经常看到一些.asset的配置文件&#xff0c;而这些文件就是用一个自定义的类去继承ScriptableObject来生成的。比如当前有一些零散特效需要预加载&#xff0c;这个时候我们可以声明一个类去保存这些零散特效对象的信息&#xff0c;然后统一读取加载。 代码&#…

JavaScript极速入门(1)

初识JavaScript JavaScript是什么 JavaScript(简称JS),是一个脚本语言,解释型或者即时编译型语言.虽然它是作为开发Web页面的脚本语言而著名,但是也应用到了很多非浏览器的环境中. 看似这门语言叫JavaScript,其实在最初发明之初,这门语言的名字其实是在蹭Java的热度,实际上和…

.jsonl 格式文件的解释

根据 CHATGPT .jsonl 文件格式是一种文本文件格式&#xff0c;通常用于存储每行一个JSON对象的数据。.jsonl 文件的每一行都是一个独立的JSON对象&#xff0c;这些对象之间没有任何分隔符。 以下是一个示例.jsonl文件的内容&#xff1a; {"name": "John"…

【LeetCode】876_链表的中间结点_C

题目描述 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 https://leetcode.cn/problems/middle-of-the-linked-list/description/ 示例 提示&#xff1a; 链表的结点数范围是 [1, 100]1 <…

Subversion svn 开源的版本控制系统入门介绍 VCS

拓展阅读 Subversion 开源的版本控制系统入门介绍 VCS Git 开源的版本控制系统-01-入门使用介绍 Git 开源的版本控制系统-02-base usage 基本用法 Git 开源的版本控制系统-03-时间数据回溯 Git 开源的版本控制系统-04-branch manage 分支管理 Git 开源的版本控制系统-05-…

SpringBoot使用Jackson 序列化小妙招

前言 SpringBoot默认使用Jackson进行json数据的序列化&#xff0c;在这个过程中总会有些奇奇怪怪的需求&#xff0c;对于这些小需求要么增加一堆配置类&#xff0c;要么重写方法&#xff0c;其实都有点杀鸡用牛刀了&#xff0c;那么我来列举下日常开发中这些小需求如何通过配置…

UE5数字孪生系列笔记(一)

智慧城市数字孪生系统 虚幻引擎连接数据库 将自己的mysql版本的libmysql.dll替换掉插件里面的libmysql.dll 然后将这个插件目录复制到虚幻项目目录下 然后添加这个插件即可 新建一个UMG&#xff0c;添加一个按钮试试&#xff0c;数据库是否连接 将UI添加到视口 打印是否连接…

力扣爆刷第87天之hot100五连刷21-25

力扣爆刷第87天之hot100五连刷21-25 文章目录 力扣爆刷第87天之hot100五连刷21-25一、240. 搜索二维矩阵 II二、160. 相交链表三、206. 反转链表四、234. 回文链表五、141. 环形链表 一、240. 搜索二维矩阵 II 题目链接&#xff1a;https://leetcode.cn/problems/search-a-2d-…

前端每日一练 :相邻元素、嵌套元素Margin 塌陷、合并问题如何额解决?

相邻元素外边距塌陷合并 表现示例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</t…

Python与FPGA——sobel边缘检测

文章目录 前言一、sobel边缘检测二、Python sobel边缘检测三、FPGA sobel边缘检测总结 前言 边缘存在于目标、背景区域之间&#xff0c;它是图像分割所依赖的较重要的依据&#xff0c;也是图像匹配的重要特征。边缘检测在图像处理和计算机视觉中&#xff0c;尤其在图像的特征提…

LVS----DR模式

一、LVS-DR工作原理 1、LVS-DR数据包流向分析 客户端发送请求到Director Server (负载均衡器)&#xff0c;请求的数据报文&#xff08;源IP是CIP&#xff0c;目标IP是VIP&#xff09;到达内核空间。Director Server 和Real Server 在同一个网络中&#xff0c;数据通过二层数据…

turtle海龟画图

10. 画笔设置 1. 画笔设置 海龟库绘制时的线条是可以设置的&#xff0c;例如画笔的颜色&#xff0c;方法名如下&#xff1a; 方法名方法说明.pencolor(‘red’)设置画笔颜色&#xff0c;例如红色 import turtle #导入海龟图库 turtle.shape(turtle) #召唤海龟 turtle.pencolo…

【vue3之组合式API及其新特性】

组合式API及其新特性 一、setup1.写法2.如何访问3.语法糖4.同步返回对象 二、reactive()和ref()1.reactive()2.ref() 三、computed四、watch函数1.侦听单个数据2.侦听多个数据3. immediate4. deep5.精确侦听对象的某个属性 五、生命周期函数六、组件通信1.父传子2. 子传父 七、…

Java开发从入门到精通(一):Java的基础语法进阶

Java大数据开发和安全开发 &#xff08;一&#xff09;Java注释符1.1 单行注释 //1.2 多行注释 /* */1.3 文档注释 /** */1.4 各种注释区别1.5 注释的特点1.5 注释的快捷键 &#xff08;二&#xff09;Java的字面量&#xff08;三&#xff09;Java的变量3.1 认识变量3.2 为什么…

(亲测可用)Adobe Photoshop 2024下载与安装

背景介绍&#xff1a;Adobe Photoshop 2024 是全球最受欢迎的图像编辑软件之一&#xff0c;2024年的版本带来了一系列令人印象深刻的功能&#xff1a; AI增强的自动选择和蒙版工具&#xff1a;现在&#xff0c;用户可以更轻松地选择和处理复杂的图像元素。更多的3D渲染功能&…

vue-treeselect的下拉列表中的字体样式修改

vue-treeselect的文件为&#xff1a;riophae/vue-treeselect/dist/vue-treeselect.css 打开这个文件&#xff0c;找到css的类.vue-treeselect__menu&#xff0c;默认值为&#xff1a; .vue-treeselect__menu { cursor: default; padding-top: 5px; padding-bottom: 5px; displ…

1、let、const、var区别、解构赋值、新增字符串语法、数组方法、网址组成

一、let、const、var的区别* 1、let和var的区别 相同点&#xff1a; 在全局声明的就是全局变量&#xff0c;在局部声明的变量是局部变量不同点&#xff08;4条&#xff09;&#xff1a; let声明的变量不能提升let声明的变量名不能重复声明let声明的变量只在当前的块作用域中有…

如何使用宝塔面板搭建Discuz并结合cpolar实现远程访问本地论坛

文章目录 前言1.安装基础环境2.一键部署Discuz3.安装cpolar工具4.配置域名访问Discuz5.固定域名公网地址6.配置Discuz论坛 前言 Crossday Discuz! Board&#xff08;以下简称 Discuz!&#xff09;是一套通用的社区论坛软件系统&#xff0c;用户可以在不需要任何编程的基础上&a…