图论练习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;
	
	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();
		    }
		}
	}

		

	

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity 给刚体一个力或速度

创建平面和小球&#xff0c;给力或给速度让其弹起 给小球挂载刚体&#xff08;Rigibdody&#xff09;和脚本 &#xff08;力是累计或者衰减的&#xff0c;直接给速度就是赋值&#xff0c;但如果速度就和力类似了&#xff09; using System.Collections; using System.Collect…

开发手札:unity2022+vscode1.87联合开发

不得不说&#xff0c;时间的力量是很强大的&#xff0c;同时熵增理论适用于任何地方。 在现在的公司干了五年多了&#xff0c;五年前配置的内网开发机&#xff0c;i7 870016g1t hddgtx1080已经卡爆了&#xff0c;特别是硬盘掉速严重&#xff0c;开机开软件没有一两分钟都…

代码随想录算法训练营第四十四天|309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费,总结

系列文章目录 代码随想录算法训练营第一天|数组理论基础&#xff0c;704. 二分查找&#xff0c;27. 移除元素 代码随想录算法训练营第二天|977.有序数组的平方 &#xff0c;209.长度最小的子数组 &#xff0c;59.螺旋矩阵II 代码随想录算法训练营第三天|链表理论基础&#xff…

CVPR 2024 | Modular Blind Video Quality Assessment:模块化无参视频质量评估

无参视频质量评估 (Blind Video Quality Assessment&#xff0c;BVQA) 在评估和改善各种视频平台并服务用户的观看体验方面发挥着关键作用。当前基于深度学习的模型主要以下采样/局部块采样的形式分析视频内容&#xff0c;而忽视了实际空域分辨率和时域帧率对视频质量的影响&am…

前端处理接口直接返回的图片

有时候接口会直接返回图片而不是连接&#xff0c;前端需要处理后才能使用。 首先你可能需要设置responseType: blob’处理响应数据格式。 直接使用 将接口及参数动态拼接成img.src直接使用 <img src"http://test.com/api/img?size50x50" alt"">i…

【Java设计模式】十一、组合模式

文章目录 1、组合模式2、案例3、总结 1、组合模式 下面的文件系统&#xff0c;树形结构&#xff0c;有文件夹节点和文件节点&#xff08;有无儿子节点的区别&#xff09;&#xff0c;使用这两种节点也要做区分。 组合模式&#xff08;部分整体模式&#xff09;&#xff0c;就…

前端运算符比较与计算中的类型转换,运算规则

题目&#xff1a; 下面表达式的值分别都是什么&#xff08;类型转换&#xff09; 0 0 0 2 true 2 false false false false 0 false undefined false null null undefined\t\r\n 0JS中的原始类型有哪些 原始值类型就是 存储的都是值&#xff0c;没有函数可以调用的。…

解决ts报错:类型“entry”上不存在属性“$AppTools”

uniapp ts 项目&#xff0c;已经将AppTools挂在了vue的原型上&#xff0c;但是在vue页面使用时报错&#xff0c;如图&#xff1a; 解决&#xff1a; 在项目根目录下的tsconfig.json文件添加如下配置&#xff1a; "include": ["src/**/*"],这样报错就消失…

32单片机基础:输入捕获测频率

接线图如下图所示&#xff1a; 我们复制之前写过的代码6-3 PWM驱动LED呼吸灯 在PWM模块中&#xff0c;执行的逻辑是&#xff0c;初始化TIM2的通道1&#xff0c;产生一个PWM波形&#xff0c;输出引脚是PA0&#xff0c;通过SetCompare1的函数&#xff0c;可以调节CCR1寄存器的值…

算法相关计算

1 内存管理相关 1 .1 float 6.9 f 的内存计算方法 二进制小数的计算&#xff1a; &#xff08;1&#xff09;小数的二进制算法和整数的大致相反&#xff0c;就是不断的拿小数部分乘以2取积的整数部分&#xff0c;然后正序排列。比如求0.9的二进制&#xff1a; 0.9*21.8 取 1…

【网络】主机连接 TCP 三次握手

【网络】主机连接 TCP 三次握手 一、TCP连接3次握手二、TCP连接4次挥手三、为什么tcp要三次握手&#xff0c;两次行不四、为什么TCP挥手需要4次五、Netstat命令的连接状态包括:六、练习题 一、TCP连接3次握手 1、建立连接的时候是3次握手&#xff0c;客户端向服务器端发送SYN&…

微软亚太区AI智能应用创新业务负责人许豪,将出席“ISIG-AIGC技术与应用发展峰会”

3月16日&#xff0c;第四届「ISIG中国产业智能大会」将在上海中庚聚龙酒店拉开序幕。本届大会由苏州市金融科技协会指导&#xff0c;企智未来科技&#xff08;AIGC开放社区、RPA中国、LowCode低码时代&#xff09;主办。大会旨在聚合每一位产业成员的力量&#xff0c;深入探索A…

手写分布式配置中心(四)增加实时刷新功能(长轮询)

上一篇文章中实现了短轮询&#xff0c;不过短轮询的弊端也很明显&#xff0c;如果请求的频率较高&#xff0c;那么就会导致服务端压力大&#xff08;并发高&#xff09;&#xff1b;如果请求的频率放低&#xff0c;那么客户端感知变更的及时性就会降低。所以我们来看另一种轮询…

(上海电力展)2024上海国际智慧电力与电气设备展览会

2024上海国际智慧电力与电气设备展览会 2024 Shanghai International Intelligent Power and Electrical Equipment Exhibition 时 间&#xff1a;2024年7月13-15日 地 点&#xff1a;上海新国际博览中心 展会简介Introduction 随着全球进入互联网和数字经济时…

精品中国货出海wordpress外贸独立站建站模板

旗袍唐装wordpress外贸网站模板 旗袍、唐装、华服wordpress外贸网站模板&#xff0c;适合做衣服生意的外贸公司官网使用。 https://www.jianzhanpress.com/?p3695 劳动防护wordpress外贸独立站模板 劳动防护wordpress外贸独立站模板&#xff0c;劳动保护、劳动防护用品外贸…

“首件检验”为什么至关重要?(内附流程规范)

在产品的设计及生产过程中&#xff0c;经常会出现设计变更、工艺变更、制程调整、非计划停线及转产、转线等“变化”。 如何确保这些“变化”不影响产品后续的生产品质&#xff1f;这就需要在作业准备验证、停产后验证阶段&#xff0c;进行不能缺少的重要环节——“首件检验”。…

VGW在 Windows 平台上局域网就绪的旁路由器程序

在查阅本篇文章之前可以查看下&#xff0c;本人前两年写的关于VGW软件路由器的文章 Linux 平台上面单网卡 TUN/TAP实现局域网其它设备上网_linux 物理网卡与tun同网段-CSDN博客 VGW软件路由器是一个工作IEEE以太网&#xff08;L2&#xff09;链路层的路由器程序&#xff0c;它…

第三讲 汇编初步 课程随手记

一、寄存器 32位CPU通用寄存器如下图所示&#xff1a; 因为教材依照的是32位CPU寄存器&#xff0c;而我安装的是64位寄存器&#xff0c;所以找了一下64位的寄存器的资料 PS&#xff1a;一般来说&#xff0c;Intel处理器字节存储顺序为小端法存储&#xff0c;是指数据的高字节保…

el-table 表格多选, 批量删除功能

一、基础的多选el-table ElementUI 提供了多选行table&#xff0c;同时若依框架也提供了成熟的多选表格。 1.table基础结构 需要绑定selection-change方法 <el-tablev-loading"loading"stripe:data"productList"selection-change"handleSelect…

常见的几种echarts类型

一&#xff1a;折线图 let option {tooltip: {},animation: false,grid: {top: "20%",bottom: "33%", //也可设置left和right设置距离来控制图表的大小left: 5%,right: 5%},xAxis: {boundaryGap:false,data: [1,2,3,4,5],axisLine: {show: true, //隐藏X轴…