图论练习5

news2025/1/20 1:38:56

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;
	
	static
	class 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) {
//			}
//		}
		static
		class 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) {
//			}
//		}
		static
		class 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.coloradmin.cn/o/1496110.html

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

相关文章

uniapp 解决请求出现 /sockjs-node/info?t=问题

1. uniapp请求出现 /sockjs-node/info?t问题 1.1. 问题 uniapp项目老是出现 http://192.168.2.106:8080/sockjs-node/info?t1709704280949 1.1. sockjs-node介绍 sockjs-node 是一个JavaScript库&#xff0c;提供跨浏览器JavaScript的API&#xff0c;创建了一个低延迟、全…

spring 注解缓存查询方法使用

spring-boot项目启动类上加注解: EnableCaching 查询方法注解: Cacheable

基于springboot的精准扶贫管理系统论文

精准扶贫管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了精准扶贫管理系统的开发全过程。通过分析精准扶贫管理系统管理的不足&#xff0c;创建了一个计算机管理精准扶贫管理系统的方案。文章介绍了精…

【Java JVM】Class 文件的加载

Java 虚拟机把描述类的数据从 Class 文件加载到内存, 并对数据进行校验, 转换解析和初始化, 最终形成可以被虚拟机直接使用的 Java 类型, 这个过程被称作虚拟机的类加载机制。 与那些在编译时需要进行连接的语言不同, 在 Java 语言里面, 类的加载, 连接和初始化过程都是在程序…

SpringBoot整合【RocketMQ】

目录 1.POM文件添加依赖及yml配置 2.RocketmqUtil 3.生产者&#xff08;异步发送示例&#xff09; 4.消费者 5.测试 1.POM文件添加依赖及yml配置 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter&l…

html--3D爱心

文章目录 代码效果 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>爱心</title><style type"text/css">*{margin: 0px;border: 0px;}body{overflow: hidden;background-…

简单整理vue-router,路由知识

1.项目中引入 1.1 安装注册 1.2 封装抽离 在main.js中 书写,会造成单个js文件过于臃肿的情况,需要将路由配置部分抽离出来,在src下新建router文件夹,新建index.js文件 import Vue from vue import VueRouter from vue-router import HomeView from ../views/HomeView.vue im…

Wireshark——获取指定协议的数据包

1、问题 使用Wireshark捕获了大量的数据包&#xff0c;但是只想要指定协议的数据包。 2、方法 例如&#xff0c;只想要Modbus/TCP协议的数据包。 在应用显示过滤器中输入协议的名称&#xff08;小写&#xff09;&#xff0c;回车。 选择文件&#xff0c;导出特定分组。 将所…

Matlab 机器人工具箱 RobotArm类

文章目录 1 RobotArm1.1 方法1.2 注意2 RobotArm.RobotArm3 RobotArm.cmove4 其他官网:Robotics Toolbox - Peter Corke 1 RobotArm 串联机械臂类 1.1 方法 方法描述plot显示机器人的图形表示teach驱动物理和图形机器人mirror使用机器人作为从机来驱动图形</

影响哈默纳科Harmonic减速机使用寿命的5大因素

哈默纳科HarmonicDrive减速机以其轻量、小型、传动效率高、减速范围广、精度高等特点&#xff0c;被广泛应用于各种传动系统中。然而&#xff0c;尽管哈默纳科Harmonic减速机具有诸多优势&#xff0c;但其使用寿命仍可能受到多种因素的影响。 首先&#xff0c;环境因素对哈默纳…

【ESP32 IDF快速入门】点亮第一个LED灯与流水灯

文章目录 前言一、有哪些工作模式&#xff1f;1.1 GPIO的详细介绍1.2 GPIO的内部框图输入模式输出部分 二、GPIO操作函数2.1 GPIO 汇总2.2 GPIO操作函数gpio_config配置引脚reset 引脚函数设置引脚电平选中对应引脚设置引脚的方向 2.3 点亮第一个灯 三、流水灯总结 前言 ESP32…

基于深度学习的苹果叶片病害检测系统(含UI界面、yolov8、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8 yolov8主要包含以下几种创新&#xff1a;         1. 可以任意更换主干结构&#xff0c;支持几百种网络主干。 数据集&#xff1a;     网上下载的数据集&#x…

UE4 Niagara 关卡1.4官方案例解析

sprites can face the camera&#xff0c;or they can face any arbitrary vector&#xff0c;in this case the vector between the center of the system and the particle itself&#xff08;粒子可以面对摄影机&#xff0c;也可以面对任意向量&#xff0c;在这个实例中的向…

为国产信创服务器提供LDAP统一身份认证方案

金融信创作为 8 大行业信创之首&#xff0c;早已成为其他行业信创建设的参考。金融行业有着极为复杂的业务场景&#xff0c;对系统有着极高的稳定可靠需求&#xff0c;因此&#xff0c;在寻找微软 AD 国产化替代方案时&#xff0c;常会涉及到更深层次的场景。例如&#xff0c;最…

免费体验重保利器!AI加持智胜攻防,企业安全巡查活动等你加入

两会时刻&#xff0c;重保启动 今年&#xff0c;亚信安全护航重保 又有新“利器”加持 新增AI智能降噪算法的 “外部攻击面管理”服务 升级加入攻防“编制” 国内TOP级攻防专家团队&#xff0c;亚信安全北极狐高级攻防实验室赋能支撑&#xff0c;正式推出“攻防利器系列行动…

【b站咸虾米】1 Vue介绍 2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例

课程地址&#xff1a;【2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例】 https://www.bilibili.com/video/BV1pz4y1S7bC/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 感觉尚硅谷的Vue看完忘得差不多了&#xff0c;且之前学过咸虾米的unia…

Python与FPGA——sobel边缘检测

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

Day37 socket、TCP、UDP

socket类型 流式套接字(SOCK_STREAM) TCP 提供了一个面向连接、可靠的数据传输服务&#xff0c;数据无差错、无重复的发送且按发送顺序接收。内设置流量控制&#xff0c;避免数据流淹没慢的接收方。数据被看作是字节流&#xff0c;无长度限制。 数据报套接字(SOCK_DGRAM) UD…

InnoDB存储引擎对MVCC的实现

MVCC MVCC的目的 在搞清楚MVCC之前,我们要搞懂一个问题,MVCC到底解决的是什么问题? 我用一句话概括,那就是为了解决读-写可以一起的问题! 在我们的印象里,InnoDB可以读读并发,不能读写并发,或者写写并发 这是很正常的想法,因为如果读写并发的化,会有并发问题 而对于写写…

设计模式:什么是设计模式?①

一、什么是设计模式&#xff1f; 1. 是一类程序设计思想 2. 是在大量实践过程中摸索总结出的标准经验提炼 3. 具有多样性和丰富性&#xff0c;不同情况应用的思想不同 二、设计模式的好处 1. 代码生产力和效率的提升 2. 让代码表现更为规整&#xff0c;简洁。阅读维护管理的成本…