【发布时间】:2018-08-27 15:27:05
【问题描述】:
我解决了它,它部分工作,但我只能使用 BFS 找到解决方案,我确信这不需要图形遍历算法,因为我们还没有完成它们,但我找不到任何其他解决方案.有人可以给我一个提示。我会将 BFS 代码发布到我实际上是如何解决这个问题的,而不是我认为应该如何解决的问题。
#include <stdio.h>
#include <stdlib.h>
char file[20][20];
int v[20], ns, n, comp, c[20];
int prim;
int ultim;
FILE *f;
int nr = 0, nl, nc;
void matrix() {
int i, j;
char c, n;
fscanf(f, "%d %d \n", &nl, &nc);
for (i = 1; i <= nl; i++) {
for (j = 1; j <= nc; j++) {
c = getc(f);
file[i][j] = c;
}
n = getc(f);
}
}
// citirea grafului din fisier text si construirea matricei de adiacenta
// afisarea pe ecran a matricei de adiacenta
void afisare() {
int i, j;
printf("Matricea : \n");
for (i = 1; i <= nl; i++)
{
for (j = 1; j <= nc; j++)
printf("%c", file[i][j]);
printf("\n");
}
}
// returnează primului nod nevizitat
int exista_nod_nevizitat(int v[20], int n) {
int i, j;
for (i = 1; i <= nl; i++)
if (v[i] == 0)
return i; // primul nod nevizitat
return 0; // nu mai exista noduri nevizitate
}
// parcurgerea în latime a unei componente conexe, plecând din nodul de start ns
void parcurgere_latime(char file[20][20], int nl, int ns) {
int i, j;
comp++;
v[ns] = 1;
prim = ultim = 1;
c[ultim] = ns;
while (prim <= ultim) {
for (i = 1; i <= nl; i++)
if (file[c[prim]][i] == 'L')
if (v[i] == 0)
{
ultim++;
c[ultim] = i;
v[i] = 1;
}
prim++;
}
}
// functia principala main()
int main() {
int set, nr;
f = fopen("in1.txt", "r");
fscanf(f, "%d \n", &set);
while (set != 0) {
matrix();
afisare();
while (exista_nod_nevizitat(v, n) != 0) {
ns = exista_nod_nevizitat(v, n);
parcurgere_latime(file, n, ns); // parcurg o alta componenta conexa
}
printf("Graful este alcătuit din ");
printf("%d", comp);
printf("componente conexe \n");
set--;
}
return 0;
}
【问题讨论】:
-
请注意,trailing white space in
scanf()formats 通常会引起麻烦。它可能对您的程序无害,但原则上应避免。 -
我认为你不需要 bfs。也许尝试连接组件的方法。 en.wikipedia.org/wiki/Connected-component_labeling
-
你需要描述你的代码在做什么,然后也许你会得到一些帮助
-
从“左上角”开始搜索,依次扫描每一行。当您遇到
L时,您会看到一个岛的最左上角(但该岛的其余部分可能在您开始的位置的左侧,但都在同一条线上或以下)。将L转换为另一个字符(例如@)。现在四处寻找已连接的L,将每个都转换为@,因为它是当前岛的一部分。当没有更多连接的L时,从您开始当前岛的位置继续前进,忽略任何@标记并寻找下一个L。这样可以避免回溯。 -
如果有
L或T形状的段,我认为问题不是格式正确的;我可以根据策略将 2 或 3 有效分解为矩形的示例。如果我们排除接触矩形,那么它可以通过在地图上进行一次扫描来完成,使用一个模板来查看当前位置、上方的元素和左侧的元素,同时扫描右侧和向下(作为 Jonathan 的简化上面的解决方案)