首页 > 其他分享 >Vova Escapes the Matrix

Vova Escapes the Matrix

时间:2024-07-21 14:18:46浏览次数:13  
标签:Matrix Escapes int 短路 push second Vova pair first

做的时候就差如何得出一个点到两个不同的出口的最短路和次短路了啊

分类讨论

如果图不能到达出口,那么可以把所有'.'都填了

如果图只能达到一个出口,那么就是所有'.'的个数减去起点到这个出口的最短路

如果图可以到达两个及以上出口,考虑填满陷阱之后,图长成什么样子:此时一定刚好还剩下两个可到达的出口,所以我们可以找到两条路;如果这两条路分叉了之后又汇聚到一个点,显然是不优的(可以把分叉的路变成一条路,从而将另一条路填上陷阱),于是这两条路一定是先一起走,然后分叉一直到两个终点,于是我们可以得出算法,先枚举分叉点,算出起点到分叉点的距离,再算分叉点到两个不同的出口的最短路和次短路即可(如果分叉点到两个不同的出口的最短路和次短路仍然有重叠,无所谓,因为我们会枚举所有点,不会遗漏最优答案)

最主要的就是如何得出一个点到两个不同的出口的最短路和次短路,此时要记录路径长度以及起点,具体见下面的代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1010;
int n,m;
pair<int,int> st;
queue<pair<int,int> > q;
queue<pair<pair<int,int>,int> > Q;
vector<pair<int,int> > e;
char s[N][N];
bool vis[N][N],mark[N][N][2];
int f[N][N][2],dist[N][N];
pair<int,int> g[N][N][2];
int dx[5]={-1,0,1,0},dy[5]={0,1,0,-1};
bool check(int x,int y)
{
	if((x==1||x==n||y==1||y==m)&&s[x][y-1]!='#') return 1;
	return 0;
}
bool valid(pair<int,int> x)
{
    if(x.first<1||x.first>n||x.second<1||x.second>m||s[x.first][x.second-1]=='#') return 0;
    return 1;
}
int bfs()
{
	int cnt=0;
	q.push(st);
	while(!q.empty())
	{
		pair<int,int> u=q.front();
		q.pop();
		if(vis[u.first][u.second]) continue;
		vis[u.first][u.second]=1;
		if(check(u.first,u.second)) cnt++;
		for(int i=0;i<4;i++)
		{
			pair<int,int> v;
			v.first=u.first+dx[i],v.second=u.second+dy[i];
			if(valid(v)) q.push(v);
		}
	}
	if(cnt<=1) return cnt;
	else return 2;
}
pair<int,int> work1()
{
    pair<int,int> res;
	q.push(st);
	dist[st.first][st.second]=0;
	while(!q.empty())
	{
		pair<int,int> u=q.front();
		q.pop();
		if(vis[u.first][u.second]) continue;
		vis[u.first][u.second]=1;
		if(check(u.first,u.second)&&dist[u.first][u.second]<1000000000) 
		res=u;
		for(int i=0;i<4;i++)
		{
			pair<int,int> v;
			v.first=u.first+dx[i],v.second=u.second+dy[i];
			if(valid(v)) 
			{
				q.push(v);
				dist[v.first][v.second]=min(dist[u.first][u.second]+1,dist[v.first][v.second]);
			}
		}
	}
	return res;
}
void work2()
{
	for(int i=0;i<e.size();i++) 
	{
		Q.push(make_pair(e[i],0));
		f[e[i].first][e[i].second][0]=0;//f表示最短路和次短路距离 
		g[e[i].first][e[i].second][0]=e[i];//g 表示最短路和次短路起点
	}
	while(!Q.empty())
	{
		pair<pair<int,int>,int> u=Q.front();
		Q.pop();
		if(mark[u.first.first][u.first.second][u.second]) continue;
		mark[u.first.first][u.first.second][u.second]=1;
		for(int i=0;i<4;i++)
		{
			pair<pair<int,int>,int> v;
			v.first.first=u.first.first+dx[i];
			v.first.second=u.first.second+dy[i];
			if(!valid(v.first)) continue;
			if(u.second==0)
			{
				if(f[v.first.first][v.first.second][0]>f[u.first.first][u.first.second][0]+1)
				{
					/*f[v.first.first][v.first.second][1]=f[v.first.first][v.first.second][0];
					g[v.first.first][v.first.second][1]=g[v.first.first][v.first.second][0];*/
					//在边长为1的情况下,上述情况是不可能发生的,所以可以注释掉 
					f[v.first.first][v.first.second][0]=f[u.first.first][u.first.second][0]+1;
					g[v.first.first][v.first.second][0]=g[u.first.first][u.first.second][0];
					Q.push(make_pair(v.first,0));
					//Q.push(make_pair(v.first,1));
				}
				else if(f[v.first.first][v.first.second][1]>f[u.first.first][u.first.second][0]+1&&g[v.first.first][v.first.second][0]!=g[u.first.first][u.first.second][0])
				{
					f[v.first.first][v.first.second][1]=f[u.first.first][u.first.second][0]+1;
					g[v.first.first][v.first.second][1]=g[u.first.first][u.first.second][0];
					Q.push(make_pair(v.first,1));
				}
			} 
			else if(f[v.first.first][v.first.second][1]>f[u.first.first][u.first.second][1]+1&&g[v.first.first][v.first.second][0]!=g[u.first.first][u.first.second][1])
			{
				f[v.first.first][v.first.second][1]=f[u.first.first][u.first.second][1]+1;
				g[v.first.first][v.first.second][1]=g[u.first.first][u.first.second][1];
				Q.push(make_pair(v.first,1));
			}
		}
	}
}
int main() 
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		e.clear();
		for(int i=1;i<=n;i++)
		{
			scanf("%s",s[i]);
			for(int j=0;j<m;j++)
			{
				if(s[i][j]=='V') st.first=i,st.second=j+1;
				if(check(i,j+1)) e.push_back(make_pair(i,j+1));
			}
		}
		for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		vis[i][j]=0;
		int type=bfs(),ans=0;
		if(!type)
		{
			for(int i=1;i<=n;i++)
			for(int j=0;j<m;j++)
			if(s[i][j]=='.') ans++;
			printf("%d\n",ans);
		} 
		else if(type==1)
		{
			for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			{
			    vis[i][j]=0;
			    dist[i][j]=0x3f3f3f3f;
			}
			pair<int,int> ed=work1();
			for(int i=1;i<=n;i++)
			for(int j=0;j<m;j++)
			if(s[i][j]!='#') ans++;
			printf("%d\n",ans-dist[ed.first][ed.second]-1);
		}
		else
		{
			for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++)
			{
				vis[i][j]=mark[i][j][0]=mark[i][j][1]=0;
				//vis用于work1的访问标记
				//mark用于work2的访问标记 
				dist[i][j]=0x3f3f3f3f;
				for(int k=0;k<=1;k++)
				f[i][j][k]=0x3f3f3f3f,g[i][j][k]=make_pair(0,0);
			}
			work2();//得出一个点到两个不同的出口的最短路和次短路 
			work1();//得出起点到某一点的最短路 
			for(int i=1;i<=n;i++)
			for(int j=0;j<m;j++)
			if(s[i][j]!='#') ans++;
			int Min=0x7fffffff;
			for(int i=1;i<=n;i++)
			for(int j=0;j<m;j++)
			if(s[i][j]!='#'&&dist[i][j+1]<0x3f3f3f3f&&f[i][j+1][0]<0x3f3f3f3f&&f[i][j+1][1]<0x3f3f3f3f) Min=min(Min,dist[i][j+1]+f[i][j+1][0]+f[i][j+1][1]);
			printf("%d\n",ans-Min-1);
		}
	}
  	return 0;
}

标签:Matrix,Escapes,int,短路,push,second,Vova,pair,first
From: https://www.cnblogs.com/dingxingdi/p/18314414

相关文章

  • G. A/B Matrix
    原题链接题解每行有a个,所以总共有\(n\cdota\)个每列有b个,所以总共有\(m\cdotb\)个所以要满足\(na=mb\)想象一下这个场景:每一行,每次往当前列中,最左端的一最少的列的开始连续放置1code#include<bits/stdc++.h>#definelllonglongusingnamespacestd;voids......
  • [LeetCode] 1380. Lucky Numbers in a Matrix
    Givenanmxnmatrixofdistinctnumbers,returnallluckynumbersinthematrixinanyorder.Aluckynumberisanelementofthematrixsuchthatitistheminimumelementinitsrowandmaximuminitscolumn.Example1:Input:matrix=[[3,7,8],[9,11,......
  • manim边学边做--Matrix
    在代数问题中,矩阵是必不可少的工具,manim中提供了一套展示矩阵(Matrix)的模块,专门用于在动画中显示矩阵格式的数据。关于矩阵的类主要有4个:Matrix:通用的矩阵IntegerMatrix:元素是整数的矩阵DecimalMatrix:元素包含小数的矩阵MobjectMatrix:元素可以是图形的矩阵其实IntegerMatrix......
  • 机器学习分类结果精度测定 - 混淆矩阵(Confusion Matrix)
    一、引言机器学习和数据科学中一个经常被忽视,但至关重要的概念是模型评估。你可能已经建立了一个非常先进的模型,但如果没有合适的评估机制,你就无法了解模型的效能和局限性。这就是混淆矩阵(ConfusionMatrix)派上用场的地方。1.1什么是混淆矩阵?混淆矩阵是一种特定的表格布局......
  • [ARC115B] Plus Matrix 的题解
    题目大意给你一个\(n\timesn\)的数组\(C\),\(c_{i,j}=a_i+b_j\),求\(a\)数组与\(b\)数组,不保证有解,其中\(1\len\le500,1\lec_{i,j}\le10^9\),而且\(a_i,b_i\)都是非负整数。\[\begin{bmatrix}a_1+b_1&a_1+b_2&\cdots&a_1+b_{n-1}&a_1+b_n\\a_2+b_......
  • 用StabilityMatrix一键安装Stable Diffusion
    StableDiffusion是2022年发布的深度学习文字到图像生成模型,它既能免费使用,又能部署在本地端,又有非常多的模型可以直接套用,在使用体验上比Midjourney和DALL-E更加强大。StableDiffusion使用的模型有下列几大类,对照模型网站https://civitai.com以形成更直观的认识:BaseModel:Sta......
  • qoj5371 Matrix (二分图匹配)
    qoj5371Matrix二分图匹配判断无解的情况,当且仅当有\(a_{i,j}\)为负数或每一行和每一列的和不相同时无解。因为\(m\leN^2\),所以我们只需要每一次至少完成一个\(a_{i,j}\)即可。观察\(B\)矩阵的形成,实际上就是一个\(i\)行只能和一个\(j\)列匹配,跑二分图匹配即可。每......
  • [题解]CF1092D1 Great Vova Wall (Version 1)
    思路发现,如果相邻元素的奇偶性相同,那么一定能通过在较低的位置竖着放若干个如果在\(i\)的位置竖着放一块砖头,使得这两列的高度相同。那么,我们想到直接考虑\(h_i\)的奇偶性,即将\(h_i\leftarrowh_i\bmod2\)。如果\(h_i=h_{i+1}\),我们显然可以同时使\(h_i\)和\(h......
  • 如何应用 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,以展示如何重叠多个内核调用队列以提供更高的性......