zoukankan      html  css  js  c++  java
  • 洛谷 P5195 【[USACO05DEC]Knights of Ni S】

    分层图题解很少啊,来个分层图哒


    这道题一开始看,我是想的跑两次最短路,一次从起点跑,一次从终点跑,然后枚举每一个灌木,但是因为起点的时候不能走骑士,所以会(WA),只有(60)分。正解分层图最短路,在找到灌木的时候,向骑士那一层连一条边即可,从起点跑一遍最短路即可。

    这里用的(SPFA) SPFA没有SPFA!!!:

    #include <bits/stdc++.h>
    using namespace std;
    int n , m , s , tot , p;
    int a[1010][1010]  , dis[2000010] , vis[2000010];
    vector<int> e[2000010];
    int id(int x , int y){	//二维压一维 
    	return (x - 1) * m + y;
    }
    void add(int x , int y){
    	e[x].push_back(y);
    }
    void spfa(int k){
    	memset(dis , 127 , sizeof(dis));
    	memset(vis , 0 , sizeof(vis));
    	queue<int> q;
    	vis[k] = 1;
    	dis[k] = 0;
    	q.push(k);
    	while(!q.empty()){
    		int x = q.front();
    		q.pop();
    		vis[x] = 1;
    		for(int i = 0; i < e[x].size(); i++){
    			int nx = e[x][i];
    			if(dis[nx] > dis[x] + 1){
    				dis[nx] = dis[x] + 1;
    				if(!vis[nx]){
    					vis[nx] = 1;
    					q.push(nx);
    				}
    			}
    		}
    	}
    }
    int main(){
    	cin >> m >> n;
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= m; j++)
    			cin >> a[i][j];
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= m; j++){
    			if(a[i][j] == 1) continue;
    			if(a[i][j] == 2) s = id(i , j);
    			if(a[i][j] == 3) p = id(i , j);
    			if(a[i][j] == 4) add(id(i , j) , id(i , j) + n * m);
    			if((a[i - 1][j] == 0 || a[i - 1][j] == 2 || a[i - 1][j] == 4) && i != 1) add(id(i , j) , id(i - 1 , j));
    			if((a[i + 1][j] == 0 || a[i + 1][j] == 2 || a[i + 1][j] == 4) && i != n) add(id(i , j) , id(i + 1 , j));
    			if((a[i][j - 1] == 0 || a[i][j - 1] == 2 || a[i][j - 1] == 4) && j != 1) add(id(i , j) , id(i , j - 1));
    			if((a[i][j + 1] == 0 || a[i][j + 1] == 2 || a[i][j + 1] == 4) && j != m) add(id(i , j) , id(i , j + 1));
    			if((a[i - 1][j] == 0 || a[i - 1][j] == 2 || a[i - 1][j] == 4 || a[i - 1][j] == 3) && i != 1) add(id(i , j) + n * m , id(i - 1 , j) + n * m);	//向上一层连边 
    			if((a[i + 1][j] == 0 || a[i + 1][j] == 2 || a[i + 1][j] == 4 || a[i + 1][j] == 3) && i != n) add(id(i , j) + n * m , id(i + 1 , j) + n * m);
    			if((a[i][j - 1] == 0 || a[i][j - 1] == 2 || a[i][j - 1] == 4 || a[i][j - 1] == 3) && j != 1) add(id(i , j) + n * m , id(i , j - 1) + n * m);
    			if((a[i][j + 1] == 0 || a[i][j + 1] == 2 || a[i][j + 1] == 4 || a[i][j + 1] == 3) && j != m) add(id(i , j) + n * m , id(i , j + 1) + n * m);
    		}
    	spfa(s);
    	cout << dis[p + n * m] - 1;	//走向上一层的时候,花费了一天,减去 
    	return 0;
    }
    
  • 相关阅读:
    forward redirect 区别
    request response 区别
    Java集合 初步了解
    通过session统计当前在线人数
    Session保存用户名到Session域对象中
    Cookie获取用户的访问记录
    表单中有关于爱好的多选框, 篮球,足球,游泳,跑步, 再有一个多选框,代表全选
    jQuery常用子元素过滤选择器
    jQuery常用属性过滤选择器
    jQuery常见可见性过滤选择器
  • 原文地址:https://www.cnblogs.com/bzzs/p/13740962.html
Copyright © 2011-2022 走看看