zoukankan      html  css  js  c++  java
  • 洛谷 P4011 孤岛营救问题【bfs】

    注意:

    • 一个点可能有多把钥匙,所以把每个点有钥匙的情况状压一下
    • 两个点之间有障碍的情况只给出了单向,存的时候记得存一下反向

    b[i][j]表示当前点拥有钥匙的状态,g[x1][y1][x2][y2]表示两点之间门的类型(0表示没有,-1表示墙比较方便),f[i][j][k]表示点(i,j)在拥有k状态钥匙的情况下的最小步数,v[i][j][k]表示f[i][j][k]的状态是否在bfs队列里。然后转移比较类似spfa

    以及终于知道为什么这种题会在24题里了…因为24全名“网络流与线性规划二十四题”…

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int inf=1e9,dx[]={1,-1,0,0},dy[]={0,0,-1,1};
    int n,m,p,t,s,g[15][15][15][15],b[15][15],f[15][15][20005];
    bool v[15][15][20005];
    struct qwe
    {
    	int x,y,s;
    }now;
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    int main()
    {
    	n=read(),m=read(),p=read(),t=read();
    	for(int i=1;i<=t;i++)
    	{
    		int x1=read(),y1=read(),x2=read(),y2=read(),z=read();
    		z=z==0?-1:z;
    		g[x1][y1][x2][y2]=z;g[x2][y2][x1][y1]=z;
    	}
    	s=read();
    	for(int i=1;i<=s;i++)
    	{
    		int x=read(),y=read(),z=read();
    		b[x][y]=b[x][y]|(1<<z);
    	}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			for(int k=0;k<(1<<14);k++)
    				f[i][j][k]=inf;
    	queue<qwe>q;
    	now.x=1,now.y=1,now.s=b[1][1];
    	f[1][1][now.s]=0;
    	v[1][1][now.s]=1;
    	q.push(now);
    	while(!q.empty())
    	{
    		int x=q.front().x,y=q.front().y,z=q.front().s;
    		v[x][y][z]=0;
    		q.pop();
    		for(int i=0;i<4;i++)
    		{
    			int x1=x+dx[i],y1=y+dy[i];
    			if(x1<1||x1>n||y1<1||y1>m||g[x][y][x1][y1]==-1||(g[x][y][x1][y1]>0&&!((1<<g[x][y][x1][y1])&z)))
    				continue;
    			int w=z|b[x1][y1];//cout<<x1<<" "<<y1<<" "<<w<<" "<<f[x1][y1][w]<<endl;
    			if(f[x1][y1][w]>f[x][y][z]+1)
    			{
    				f[x1][y1][w]=f[x][y][z]+1;
    				if(!v[x1][y1][w])
    				{
    					now.x=x1,now.y=y1,now.s=w;
    					v[x1][y1][w]=1;
    					q.push(now);
    				}
    			}
    		}
    	}
    	int ans=inf;
    	for(int i=0;i<(1<<14);i++)
    		ans=min(ans,f[n][m][i]);
    	printf("%d
    ",ans==inf?-1:ans);
    	return 0;
    }
    
  • 相关阅读:
    函数进阶:闭包、装饰器、列表生成式、生成器、迭代器
    函数基础:内置函数
    Python函数基础---参数、变量
    python函数基础:嵌套函数、作用域、匿名函数、高阶函数、递归函数
    三元运算、文件操作
    Python终端如何输出彩色字体
    文件处理: read、readline、 readlines()
    16进制、编码问题
    JSON 操作与转化
    高并发和大型网站架构相关
  • 原文地址:https://www.cnblogs.com/lokiii/p/8439723.html
Copyright © 2011-2022 走看看