首页 > 其他分享 >家访(图论建模)

家访(图论建模)

时间:2024-08-24 09:07:12浏览次数:11  
标签:小明 图论 障碍 int 边权 建模 一列 dis 家访

第1题     家访 查看测评数据信息

小明的老师应为小明平时的表现,要去小明家家访,小明所住的城市可看做一个二维网格,其中字符#表示障碍,‘.’表示空地。小明的老师住在左上角(1,1),小明住在右下角(n,m)。小明的老师要去小明家玩。小明的老师如果走到空地侧不需要任何代价,但是如果要走到障碍点则他需要先摧毁该障碍。每次可以走到相邻的四个方向之一,即从(x,y)可以走到(x+1,y),(x-1,y),(x,y+1),(x,y-1)。小明的老师可以花费C[i]的代价将第i列的所有障碍都消灭。请帮小明的老师计算她去小明家最少需要多少代价。

输入格式

 

第一行两个正整数n,m,表示网格图的大小

接下来n行,每行m个字符,描述网格图,字符仅由‘.’和‘#’组成,保证起点一定是空地

接下来一行m个数,表示C[i]

1<=n,m<=100,1<=C[i]<=1e5

 

输出格式

 

输出一个整数

 

输入/输出例子1

输入:

4 4

.##.

.#.#

.###

..#.

5 3 9 4

 

输出:

7

 

样例解释

 

消除第2列和第4列的障碍,总代价为7

 

 

建模:要如何抽象的变成图论,如何建图

可以借助虚拟点(代表某些特定的点,比如代表指定一列的点)完成一些复杂度较高的操作。

方法1:

建完图之后跑个最短路就好了

建图:
对于每一个非障碍点,可以向四周连边,没障碍边权就是0,有障碍边权是a[到四周的那一列],因为你想要从上一个点到达四周的新点,且新点这里有障碍,你就得先破除新点的障碍,所以破除花费就是新点处在的列。

但是我们发现,对于同一列,如果相邻三个点都有障碍,这个时候从第一个点到第二个点,然后从第二个点到第三个点,就会花费两倍破这一列墙的花费,但是实际上只用花费一次这一列的破墙操作,这样可以把整列破掉。我们想要处理一下怎么防止重复算。

我们可以对于每一列,每个点都向每个点连一条边权是a[这一列]的边,但这样复杂度就超限了

我们想,能不能用一个点,代表这一列的所有点,我们称为特殊点,然后这样就只需要这个特殊的点和这一列的点有关系就行了。

对每一列建立一个虚拟点,虚拟点向这一列连边,边权0,就可以有效解决。

但是虚拟点不能只有出度,什么点可以进入虚拟点?

前一列向虚拟点连边,边权a[这一列],这样也同时确保了不会算多破墙操作的花费

但是注意一下,第一列前面没有列了,那只能是第一列每个点向虚拟点连边了。

#include <bits/stdc++.h>
using namespace std;
const int N=505, M=101, M2=250000;

struct node
{
	int v, w;
	bool operator <(const node &A) const
	{
		return w>A.w;
	};
};
int n, m, w[N], dis[N*N], vis[N*N];
int dx[]={0, 0, 1, -1}, dy[]={1, -1, 0, 0};
char c[N][N];
vector<node> a[N*N*2];
priority_queue<node> q;
void dij()
{
	memset(dis, 63, sizeof dis);
	memset(vis, 0, sizeof vis);
	dis[1*M+1]=0;
	q.push({1*M+1, 0});
	
	while (!q.empty())
	{
		int u=q.top().v;
		q.pop();
		
		if (vis[u]) continue;
		vis[u]=1;
		
		for (int i=0; i<a[u].size(); i++)
		{
			int v=a[u][i].v, w=a[u][i].w;
			if (dis[v]>dis[u]+w)
			{
				dis[v]=dis[u]+w;
				q.push({v, dis[v]});
			}
		}
	}
}
int main()
{
//	freopen("1.in", "r", stdin);
	
	scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++)
		for (int j=1; j<=m; j++) cin>>c[i][j];
	
	for (int i=1; i<=m; i++) scanf("%d", &w[i]);
	
	for (int i=1; i<=n; i++)
		for (int j=1; j<=m; j++)
			for (int k=0; k<4; k++)
			{
				int nx=i+dx[k], ny=j+dy[k];
				if (nx>=1 && nx<=n && ny>=1 && ny<=m)
				{
					if (c[nx][ny]=='.') a[i*M+j].push_back({nx*M+ny, 0});
					else a[i*M+j].push_back({nx*M+ny, w[ny]});
				}
			}
	
	for (int i=1; i<=n; i++)
		for (int j=1; j<=m; j++)
		{
			if (j==1) a[i*M+j].push_back({j+M2, w[j]});
		    else a[i*M+j-1].push_back({j+M2, w[j]});
			a[j+M2].push_back({i*M+j, 0});
		}
	
	//for (int i=1; i<=n; i++) a[i*m+1].push_back({1+M2, w[1]});
	dij();
	
	printf("%d", dis[n*M+m]);
	return 0; 
} 
/*
4 3
.##
#..
##. 
...
1 2 3
*/

  

 

 

方法2:
贪心思想
破这一列的障碍后,肯定不会往回走,因为可以直接到这一列的任意位置
建一个大点,代表这列的所有点

入度:这一列全部点,上一列全部点,边权a[这一列]
出度:下一列可走点,边权0

 

两个差不多了,看懂方法一这个就ok了

 

 

 

 

 

标签:小明,图论,障碍,int,边权,建模,一列,dis,家访
From: https://www.cnblogs.com/didiao233/p/18377345

相关文章

  • 最小步数(图论建模)
    第2题   最小步数 查看测评数据信息小明来到了一个矩形迷官,每个房间写着一个数字。小明初始在左上角的房间,她准备前往该迷言的右下角房间,每次小明可以向右或者向下行走一步。另外,小明可以进行若干次传送,每次可以花费1的步数,前往和当前房间不互素的任意一个房间。现在,小明......
  • 「代码随想录算法训练营」第四十五天 | 图论 part3
    目录101.孤岛的总面积DFS思路BFS思路102.沉没孤岛103.水流问题104.建造最大岛屿101.孤岛的总面积题目链接:https://kamacoder.com/problempage.php?pid=1173文章讲解:https://programmercarl.com/kamacoder/0101.孤岛的总面积.html题目状态:看题解DFS思路思路:代码结构......
  • 【保奖资料】2024年数学建模国赛B题保奖思路获取入口(后续会更新)
    您的点赞收藏是我继续更新的最大动力!一定要点击如下的卡片链接,那是获取资料的入口!现分享2022年数学建模国赛B题资料分享,供大家学习:B题公式和算法文档解释第一问根据题目可知以下几点无人机被动测距只能测得两个发射机的夹角,但是不能知道发射机位于接收机的绝对方位,因此......
  • 【保奖资料】2024年数学建模国赛B题保奖思路获取入口(后续会更新)
    您的点赞收藏是我继续更新的最大动力!一定要点击如下的卡片链接,那是获取资料的入口!现分享2022年数学建模国赛B题资料分享,供大家学习:B题公式和算法文档解释第一问根据题目可知以下几点无人机被动测距只能测得两个发射机的夹角,但是不能知道发射机位于接收机的绝对方位,因此......
  • UVM中的TLM(事务级建模)通信(1)
    1.验证平台内部的通信    我们希望在验证平台内部找到两个component之间适合通信的方法,在接触TLM之前,想到的方法无非有采用全局变量、通过config_db传输等等。然而全局变量因为安全性不高,是我们长期以来竭力避免使用的方法;config_db虽然相对安全,但需要拉入basetest的......
  • MATLAB进行神经网络建模的案例
    下面是一个使用MATLAB进行神经网络建模的案例,该案例涉及使用神经网络来逼近一个未知系统的输入输出关系。这个案例与您提到的学习资料中的实例类似,但我会简化并解释每个步骤。案例背景假设我们有一组输入和输出数据,我们希望通过建立一个神经网络模型来逼近这些数据之间的......
  • 图论
    最短路差分约束生成树AGC004D有\(n\)个城市,每个城市有一个传送点,都可以传送到唯一的一个城市,保证从任何位置出发经过若干次传送之后能够到达\(1\)号城市。现在希望修改一些点的目的地,使得从任何一点出发在传送\(K\)次之后恰好都能到达\(1\)号城市,求最少要改变目的地......
  • 「代码随想录算法训练营」第四十四天 | 图论 part2
    200.岛屿数量题目链接:https://leetcode.cn/problems/number-of-islands/description/文章讲解:https://programmercarl.com/kamacoder/0099.岛屿的数量深搜.html题目难度:中等题目状态:看题解思路一:深搜版方法dfs:参数:接受一个字符网格grid和当前坐标(r,c)。功能:......
  • 短视频图文带货:计划建模的深度解析与实践
    随着数字营销的快速发展,短视频图文带货已经成为了一种日益重要的营销手段。相较于传统的营销方式,短视频图文带货具有更高的互动性和传播性,能够更好地吸引和留住用户。然而,如何做好短视频图文带货并非易事。许多商家和品牌虽然投入了大量的人力物力,但最终效果并不理想。这其中的......
  • 【阻抗建模、验证扫频法】光伏并网逆变器扫频与稳定性分析(包含锁相环电流环)(Simulink
    ......