• 洛谷 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;
    }
    
  • 相关阅读:
    JS两个页面通过URL传值
    新起点 新开始
    Spring Boot 常见标签
    关于Redis缓存数据库
    JPA问题汇总
    Dynamic 报表服务开发
    Dynamic crm自定义页面
    Dynamic 根据用户的角色权限设置相应的按钮显示
    Dynamic 工具类
    Dynamic 点击按钮,弹出一个漂浮页面
  • 原文地址:https://www.cnblogs.com/lokiii/p/8439723.html
Copyright © 2020-2023  润新知