• 洛谷 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;
    }
    
  • 相关阅读:
    第五篇
    第四篇
    PAT Basic 1094 谷歌的招聘 (20 分)
    PAT Basic 1093 字符串A+B (20 分)
    Dubbo 04 服务化最佳实现流程
    Dubbo 03 Restful风格的API
    Dubbo 02 微信开发
    Dubble 01 架构模型&start project
    PAT Basic 1020 月饼 (25 分)
    PAT Basic 1019 数字黑洞 (20 分)
  • 原文地址:https://www.cnblogs.com/bzzs/p/13740962.html
Copyright © 2020-2023  润新知