如题,这道题我的想法是用 kosaraju 把网格图上的 0 环缩成点再来跑计数,但是过不了 5#,不太清楚是不是这个做法本身就有问题,求助各位巨佬 qwq
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 30, M = 30;
const int dx[9] = {1, -1, 1, -1, 2, -2, 2, -2};
const int dy[9] = {2, -2, -2, 2, 1, -1, -1, 1};
int n, m, a[N + 3][M + 3];
int stx, sty, edx, edy, dis[N + 10][M + 10];
bool vis[N + 10][M + 10];
struct node {
int x, y;
node(int X, int Y) {
x = X, y = Y;
}
};
bool judge(int x, int y) {
return ((x >= 1 && x <= n) && (y >= 1 && y <= m));
}
struct piar {
int x, y, val;
bool operator < (const piar &other) {
return val < other.val;
}
};
int deg[N * M + 10];
vector <int> gra[N * M + 3], ngr[N * M + 3];
int getnum(int x, int y) {
return (x - 1) * m + y;
}
void bfs() {
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[stx][sty] = 0;
deque <node> que;
que.push_back(node(stx, sty));
while(!que.empty()) {
node fr = que.front(); que.pop_front();
int x = fr.x, y = fr.y;
if(vis[x][y]) continue;
vis[x][y] = 1;
for(int i = 0; i < 8; i++) {
int xx = x + dx[i];
int yy = y + dy[i];
if(!judge(xx, yy)) continue;
if(judge(xx, yy) && !vis[xx][yy]) {
if(a[xx][yy] == 2) continue;
else if(a[xx][yy] != 0) {
if(dis[xx][yy] > dis[x][y]) {
dis[xx][yy] = dis[x][y];
que.push_front(node(xx, yy));
}
}
else if(a[xx][yy] == 0) {
if(dis[xx][yy] > dis[x][y] + 1) {
dis[xx][yy] = dis[x][y] + 1;
que.push_back(node(xx, yy));
}
}
}
}
}
vector <piar> vec;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
vec.push_back((piar){i, j, dis[i][j]});
sort(vec.begin(), vec.end());
for(int i = 0; i < vec.size(); i++) {
int x = vec[i].x, y = vec[i].y, v = vec[i].val;
for(int p = 0; p < 8; p++) {
int xx = x + dx[p], yy = y + dy[p];
if(!judge(xx, yy)) continue;
int w = 0;
if(a[xx][yy] == 2) continue;
if(a[xx][yy] == 0) w = 1;
if(dis[xx][yy] == v + w) {
gra[getnum(x, y)].push_back(getnum(xx, yy));
ngr[getnum(xx, yy)].push_back(getnum(x, y));
}
}
}
}
int q[N * M + 10], tot = 0;
bool Vis[N * M + 10];
void dfs1(int u) {
Vis[u] = 1;
for(int i = 0; i < ngr[u].size(); i++) {
int v = ngr[u][i];
if(Vis[v]) continue;
dfs1(v);
}
q[++tot] = u;
}
bool havedge[N * M + 10][M * N + 10];
int col[N * M + 10], cl = 0;
void dfs2(int u) {
col[u] = cl;
for(int i = 0; i < gra[u].size(); i++) {
int v = gra[u][i];
if(col[v]) continue;
dfs2(v);
}
}
ll g[N * M + 3];
void kj() {
for(int i = 1; i <= n * m; i++)
if(!Vis[i]) dfs1(i);
for(int i = tot; i >= 1; i--) {
int u = q[i];
if(!col[u]) {
cl++;
dfs2(u);
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++)
cout << col[getnum(i, j)] << ' ';
cout << endl;
}
for(int u = 1; u <= n * m; u++)
ngr[u].clear();
for(int u = 1; u <= n * m; u++) {
for(int i = 0; i < gra[u].size(); i++) {
int v = gra[u][i];
if(col[u] != col[v]) {
if(!havedge[col[u]][col[v]]) {
havedge[col[u]][col[v]] =
havedge[col[v]][col[u]] = 1;
ngr[col[u]].push_back(col[v]);
deg[col[v]]++;
}
}
}
}
queue <int> que;
for(int i = 1; i <= cl; i++)
if(!deg[i]) {
g[i] = 1;
que.push(i);
}
int cnt = 0;
while(!que.empty()) {
cnt++;
int u = que.front(); que.pop();
for(int i = 0; i < ngr[u].size(); i++) {
int v = ngr[u][i];
deg[v]--;
g[v] += g[u];
if(!deg[v]) que.push(v);
}
}
cout << cnt << ' ' << cl << endl;
if(dis[edx][edy] > N * M) {
cout << -1 << endl;
return ;
}
cout << dis[edx][edy] << '\n' << g[col[getnum(edx, edy)]] << '\n';
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cin >> a[i][j];
if(a[i][j] == 3)
stx = i, sty = j;
else if(a[i][j] == 4)
edx = i, edy = j;
}
}
bfs();
kj();
}