萌新求助最短路计数
查看原帖
萌新求助最短路计数
350270
CatFromMars楼主2024/11/9 21:21

如题,这道题我的想法是用 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();
}
2024/11/9 21:21
加载中...