2018-2019 ACM-ICPC, Asia Jiaozuo Regional Contest F - Honeycomb(簡單最短路 + 噁心建圖)

題目鏈接

題意:在一個蜂巢裏,一隻小蜜蜂要從 S 點飛到 T 點。

題解:題目已經保證蜂巢的結構一定是樣例給定的框架,那麼我們可以給按照規律從左到右,從上到下給每個六邊形編號。再用bfs連邊,最後跑一遍最短路即可,思路簡單,只是連邊過程有點考驗碼力。


  +---+       +---+
 /     \     /     \
+       +---+       +---+
 \           \     /     \
  +   +   S   +---+   T   +
 /     \     /           /
+       +---+       +   +
 \           \     /     \
  +---+       +---+       +
 /                       /
+       +---+       +   +
 \                 /     \
  +---+       +---+       +
       \     /     \     /
        +---+       +---+

 

#include<bits/stdc++.h>
using namespace std;
#define pi pair<int, int>
const int N = 1e3 + 10, M = 1e6 + 100;
char s[N * 4][N * 6];
int n, m, r, c, st, en, cnt;
int vis[M], dis[M], mp[N * 4][N * 6];
int d[7][2] = {-2, -6, -4, 0, -2, 6, 2, 6, 4, 0, 2, -6};
int di[2][2] = {-2, 6, 2, 6};
vector<int>e[M];

inline void read(){//將圖讀入 
	n = r * 4 + 3;
	m = c * 6 + 3;
	for(int i = 0; i <= n + 10; ++i)
	for(int j = 0; j <= m + 10; ++j)
	s[i][j]='\0', mp[i][j] = 0;
	getchar();
	for(int i = 1; i <= n; ++i){
		char ch;
		cnt = 0;
		while((ch = getchar()) != '\n')
		s[i][++cnt] = ch;
	}
}

inline void init(){//初始化,並給中心點編號 
	for(int i = 0; i <= r * c + 10; ++i) {
		vis[i] = 0;
		e[i].clear();
	}
	cnt = 0;
	for(int i = 1; i <= r; ++i){
		int x = 3 + (i - 1) * 4, y = 5;
		int dx = x, dy = y;
		for(int j = 1; j <= c; ++j){	
			mp[dx][dy] = ++cnt;
			if(s[dx][dy] == 'S') st = cnt;
			if(s[dx][dy] == 'T') en = cnt;
			dx = dx + di[j % 2][0];
			dy = dy + di[j % 2][1];
		}
	}
}
inline int check(int dx, int dy, int x, int y){
	if(dx < 1 || dx > n || dy < 1 || dy > m) return 0;
	int mx = (dx + x) / 2;
	int my = (dy + y) / 2;
	if(s[mx][my] == ' ') return 2;
	return 1;
}

inline void bfs(){//bfs連邊 
	queue<pi>q;
	q.push(pi(3, 5));
	while(!q.empty()){
		pi t = q.front();
		q.pop();
		int u = mp[t.first][t.second];
		if(vis[u]) continue;
		vis[u] = 1;
		for(int i = 0; i < 6; ++i){
			int dx = t.first + d[i][0];
			int dy = t.second + d[i][1];
			int tmp = check(dx, dy, t.first, t.second);
			if(tmp){
				int v = mp[dx][dy];
				if(tmp == 2){
					e[u].push_back(v);
					e[v].push_back(u);
				}
				if(!vis[v]) q.push(pi(dx, dy));
			}
		} 
	}
}
struct node{
	int pos, w;
	bool friend operator < (node c, node d){
		return c.w > d.w;
	}
};
inline void dij(){//dij最短路 
	priority_queue<node>q;
	q.push(node{st, 1});
	for(int i = 0; i < cnt + 10; ++i) vis[i] = 0, dis[i] = 1e9;
	dis[st] = 1; 
	while(!q.empty()){
		node t = q.top();
		q.pop();
		int u = t.pos;
		if(vis[u]) continue;
		vis[u] = 1;
		for(auto v : e[u]){
			if(dis[v] > dis[u] + 1){
				dis[v] = dis[u] + 1;
				q.push(node{v, dis[v]});
			}
		}
	}
	if(dis[en] == 1e9) puts("-1");
	else printf("%d\n", dis[en]);
}
int main()
{
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d%d", &r, &c);
		read();
		init();
		bfs();
		dij();
	}
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章