zoukankan      html  css  js  c++  java
  • 网络流24题 之十四 孤岛营救问题 分层图

    题目大意:一张网格图,上面有一些点可能有某种钥匙。节点和节点之间可能有门。有些门须要特定的钥匙就能够通过,有些不管怎样都过不去。求从(1,1)開始到(m,n)的最短时间。


    思路:分层图+状态压缩。

    f[i][j][k],当中i和j描写叙述的是当前所在的位置。k是压缩了的当前有哪些钥匙(因为钥匙的数量<=10,所以全部的状态1<<10的空间内就能够搞定)。然后向四个方向更新的时候推断能否经过门。


    CODE:


    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define MAX 20
    #define INF 0x3f3f3f3f
    using namespace std;
    const int dx[] = {0,1,-1,0,0};
    const int dy[] = {0,0,0,1,-1};
    
    struct Complex{
    	int x,y,status;
    
    	Complex(int _,int __,int ___):x(_),y(__),status(___) {}
    	Complex() {}
    };
    
    int m,n,p,doors,keys;
    int f[MAX][MAX][1 << 11];
    bool v[MAX][MAX][1 << 11];
    int map[MAX][MAX][MAX][MAX];
    int key[MAX][MAX];
    
    void SPFA();
    inline bool Accelerator(int x1,int y1,int x2,int y2,int status);
    
    int main()
    {
    	cin >> m >> n >> p >> doors;
    	memset(map,-1,sizeof(map));
    	for(int a,b,c,d,x,i = 1;i <= doors; ++i) {
    		scanf("%d%d%d%d%d",&a,&b,&c,&d,&x);
    		map[a][b][c][d] = map[c][d][a][b] = x;
    	}
    	cin >> keys;
    	for(int x,y,z,i = 1;i <= keys; ++i) {
    		scanf("%d%d%d",&x,&y,&z);
    		key[x][y] |= 1 << z;
    	}
    	SPFA();
    	int ans = INF;
    	for(int i = 0;i < (1 << 11); ++i)
    		ans = min(ans,f[m][n][i]);
    	if(ans == INF)	ans = -1;
    	cout << ans << endl;
    	return 0;
    }
    
    void SPFA()
    {
    	memset(f,0x3f,sizeof(f));
    	f[1][1][0] = 0;
    	static queue<Complex> q;
    	while(!q.empty())	q.pop();
    	q.push(Complex(1,1,0));
    	while(!q.empty()) {
    		Complex now = q.front(); q.pop();
    		v[now.x][now.y][now.status] = false;
    		int _status = now.status;
    		if(key[now.x][now.y])	_status |= key[now.x][now.y];
    		for(int i = 1;i <= 4; ++i) {
    			int fx = now.x + dx[i];
    			int fy = now.y + dy[i];
    			if(!fx || !fy || fx > m || fy > n)	continue;
    			if(Accelerator(now.x,now.y,fx,fy,_status))
    				if(f[fx][fy][_status] > f[now.x][now.y][now.status] + 1) {
    					f[fx][fy][_status] = f[now.x][now.y][now.status] + 1;
    					if(!v[fx][fy][_status])
    						v[fx][fy][_status] = true,q.push(Complex(fx,fy,_status));
    				}
    		}
    	}
    }
    
    inline bool Accelerator(int x1,int y1,int x2,int y2,int status)
    {
    	int need_key = map[x1][y1][x2][y2];
    	if(!need_key)	return false;
    	if(need_key == -1)	return true;
    	return (status >> need_key)&1;
    }


  • 相关阅读:
    洛谷 P3353【在你窗外闪耀的星星】
    SpirngMVC源码分析
    处理器映射器(HandlerMapping)及处理器适配器(HandlerAdapter)详解(二)
    关于 DispatcherServlet.properties 文件
    处理器映射器(HandlerMapping)及处理器适配器(HandlerAdapter)详解(一)
    SpringMVC的入门程序
    Spring工作原理:初识SpringMVC
    Spring的事务管理
    Spring配置连接池和 Dao 层使用 jdbcTemplate
    Spring 的 jdbcTemplate 操作
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5078806.html
Copyright © 2011-2022 走看看