课程目录展开/折叠
- 课程直播回放
- 第1课 编程学习与提升
- 第2课 线性表的实现与应用
- 第3课 线性表、链表的实现与应用
- 第4课 链表的实现与应用
- 第5课 链表的实现与应用
- 第6课 链表的实现与应用
- 第7课 链表的实现与应用
- 第8课 链表的实现与应用
- 第9课 栈的实现与应用
- 第10课 栈的实现与应用
- 第11课 队列的实现与应用(补录)
- 第12课 队列的实现与应用
- 第13课 队列的实现与应用
- 第14课 字符串的实现与应用
- 第15课 字符串的实现与应用
- 第16课 字符串的实现与应用
- 第17课 递归和二叉树
- 第18课 递归和二叉树
- 第19课 二叉树
- 第20课 二叉树
- 第21课 二叉树
- 第22课 二叉树
- 第23课 二叉树
- 第24课 二叉树
- 第25课 二叉树
- 第26课 树、森林、二叉树、哈夫曼树和哈夫曼编码
- 第27课 哈夫曼树和哈夫曼树编码
- 第28课 哈夫曼树和哈夫曼树编码
- 第29课 二叉堆和优先队列
- 第30课 二叉堆和优先队列
- 第31课 树的表示、存储和操作
- 第32课 树的表示、存储和操作
- 第33课 树的表示、存储和操作
- 第34课 树、二叉树的知识总结
- 第35课 图的实现与应用
- 第36课 图的实现与应用
- 第37课 图的实现与应用
- 第38课 图的实现与应用
- 第39课 图的实现与应用
- 第40课 图的实现与应用
- 第41课 图的实现与应用试学
- 第42课 图的实现与应用试学
- 第43课 图的实现与应用试学
- 第44课 图的实现与应用试学
- 第45课 数据结构课程学习总结及后续提升规划试学
第44课 图的实现与应用
播放快捷键
播放/暂停:空格(或鼠标单击) 全屏:F(或鼠标双击) 退出全屏:Esc
快进10 / 30 / 60秒:方向键→ / Ctrl + 方向键→ / Shift + 方向键→
快退10 / 30 / 60秒:方向键← / Ctrl + 方向键← / Shift + 方向键←
本节课讲解配套PPT&板书:







本节课讲解到的源代码
源代码下载:第44课 图的实现与应用-源代码下载
1. C1136-红黑瓷砖-1
#include <bits/stdc++.h>
using namespace std;
char mp[25][25];
bool vis[25][25];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int W, H; // W是列 H是行
int ans;
void dfs(int x, int y)
{
vis[x][y] = true;
ans ++;
for (int d = 0; d < 4; d ++)
{
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
if (mp[nx][ny] == '#') continue;
if (vis[nx][ny]) continue;
dfs(nx, ny);
}
}
int main()
{
while (cin >> W >> H)
{
if (W == 0 && H == 0) break;
ans = 0;
memset(mp, 0x00, sizeof(mp));
memset(vis, 0x00, sizeof(vis));
int xq, yq;
for (int i = 0; i < H; i ++)
{
for (int j = 0; j < W; j ++)
{
cin >> mp[i][j];
if (mp[i][j] == '@')
{
xq = i;
yq = j;
}
}
}
dfs(xq, yq);
cout << ans << endl;
}
return 0;
}
2. C1136-红黑瓷砖-2
#include <bits/stdc++.h>
using namespace std;
/*
struct Point {
int x;
int y;
};
*/
char mp[25][25];
bool inq[25][25];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
int W, H; // W是列 H是行
int ans;
void bfs(int x, int y)
{
/*
queue<Point> q;
q.push({x, y});
*/
queue<int> qx;
queue<int> qy;
qx.push(x);
qy.push(y);
inq[x][y] = true;
while (!qx.empty())
{
int fx = qx.front();
int fy = qy.front();
ans ++;
qx.pop();
qy.pop();
for (int d = 0; d < 4; d ++)
{
int nx = fx + dx[d];
int ny = fy + dy[d];
if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
if (mp[nx][ny] == '#') continue;
if (inq[nx][ny]) continue;
qx.push(nx);
qy.push(ny);
inq[nx][ny] = true;
}
}
}
int main()
{
const char endl = '\n';
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> W >> H)
{
if (W == 0 && H == 0) break;
ans = 0;
memset(mp, 0x00, sizeof(mp));
memset(inq, 0x00, sizeof(inq));
int xq, yq;
for (int i = 0; i < H; i ++)
{
for (int j = 0; j < W; j ++)
{
cin >> mp[i][j];
if (mp[i][j] == '@')
{
xq = i;
yq = j;
}
}
}
bfs(xq, yq);
cout << ans << endl;
}
return 0;
}
3. C1136-红黑瓷砖-3
#include <bits/stdc++.h>
using namespace std;
struct point {
int x;
int y;
point()
{
x = y = 0;
}
point(int i, int j)
{
x = i;
y = j;
}
};
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
char mp[100][100];
bool inq[100][100];
int m, n; // m行 n列
point q[1000];
int f, r;
void bfs(int i, int j)
{
f = r = 0;
point p1(i, j);
q[r++] = p1;
inq[i][j] = true;
while (f != r)
{
point p = q[f];
f ++;
for (int d = 0; d < 4; d ++)
{
int ni = p.x + dx[d];
int nj = p.y + dy[d];
if (ni < 0 || ni >= m || nj < 0 || nj >= n) continue;
if (inq[ni][nj]) continue; // 不要重复入队
if (mp[ni][nj] != '.') continue;
point np(ni, nj);
q[r++] = np;
inq[ni][nj] = true;
}
}
}
int main()
{
// cout << sizeof(mp) << endl;
while (cin >> n >> m)
{
if (n == 0 && m == 0) break;
memset(mp, 0x00, sizeof(mp));
memset(inq, 0x00, sizeof(inq));
int xq, yq;
for (int i = 0; i < m; i ++)
{
for (int j = 0; j < n; j ++)
{
cin >> mp[i][j];
if (mp[i][j] == '@')
{
xq = i;
yq = j;
}
}
}
bfs(xq, yq); // 从xq,yq开始染色
cout << r << endl; // 最后队列的大小就是联通块的大小
}
/*
// 下面也是一种求连通块大小的方法,变量inq数组,为true的代表被染色过了,染色过了就代表可以到达的黑色瓷砖
int cnt = 0;
for (int i = 0; i < m; i ++)
{
for (int j = 0; j < n; j ++)
{
if (inq[i][j] == true) cnt ++;
}
}
cout << cnt << endl;
*/
return 0;
}
4. P1148-发现油田-1
#include <bits/stdc++.h>
using namespace std;
char mp[105][105];
int m, n;
int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
int ans;
// 从(x, y)这个点开始DFS
// 特征:dfs过的点,设置为* // 从(x, y)出发开始染色
void dfs(int x, int y)
{
mp[x][y] = '*';
for (int d = 0; d < 8; d ++)
{
int nx = x + dx[d];
int ny = y + dy[d];
if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
if (mp[nx][ny] == '*') continue;
// if (vis[nx][ny]) continue;
dfs(nx, ny);
}
}
// 对所有的点进行DFS,全局染色
void dfs2()
{
for (int i = 0; i < m; i ++)
{
for (int j = 0; j < n; j ++)
{
if (mp[i][j] == '@')
{
ans ++;
dfs(i, j);
}
}
}
}
int main()
{
const char endl = '\n';
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> m >> n)
{
if (m == 0) break;
ans = 0;
memset(mp, 0x00, sizeof(mp));
for (int i = 0; i < m ; i ++)
{
for (int j = 0; j < n; j ++)
cin >> mp[i][j];
}
dfs2();
cout << ans << endl;
/*
for (int i = 0; i < m; i ++)
{
for (int j = 0; j < n; j ++)
{
dfs(i, j);
}
}
*/
}
return 0;
}
5. P1148-发现油田-2
#include <bits/stdc++.h>
using namespace std;
struct Point {
int x;
int y;
};
char mp[105][105];
int m, n;
int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
int ans;
// 从一个点开始染色(遍历)
void bfs(int x, int y)
{
queue<Point> q;
q.push({x, y});
// inq[x][y] = true; 不需要了
mp[x][y] = '*';
while (!q.empty())
{
Point p = q.front();
q.pop();
for (int d = 0; d < 8; d ++)
{
int nx = p.x + dx[d];
int ny = p.y + dy[d];
if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
if (mp[nx][ny] == '*') continue;
q.push({nx, ny});
mp[nx][ny] = '*'; // 替代掉inq数组的作用
}
}
}
// 全局染色
void bfs2()
{
for (int i = 0; i < m; i ++)
{
for (int j = 0; j < n; j ++)
{
if (mp[i][j] == '@')
{
ans ++;
bfs(i, j);
}
}
}
}
int main()
{
const char endl = '\n';
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> m >> n)
{
if (m == 0) break;
ans = 0;
memset(mp, 0x00, sizeof(mp));
for (int i = 0; i < m ; i ++)
{
for (int j = 0; j < n; j ++)
cin >> mp[i][j];
}
bfs2();
cout << ans << endl;
}
return 0;
}
6. P1148-发现油田-3
#include <bits/stdc++.h>
using namespace std;
struct Point {
int x;
int y;
};
char mp[105][105];
int m, n;
bool inq[105][105];
int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
int ans;
// 从一个点开始染色(遍历)
void bfs(int x, int y)
{
queue<Point> q;
q.push({x, y});
inq[x][y] = true;
// mp[x][y] = '*';
while (!q.empty())
{
Point p = q.front();
q.pop();
for (int d = 0; d < 8; d ++)
{
int nx = p.x + dx[d];
int ny = p.y + dy[d];
if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
if (mp[nx][ny] == '*') continue;
if (inq[nx][ny]) continue;
q.push({nx, ny});
// mp[nx][ny] = '*'; // 替代掉inq数组的作用
inq[nx][ny] = true;
}
}
}
// 全局染色
void bfs2()
{
for (int i = 0; i < m; i ++)
{
for (int j = 0; j < n; j ++)
{
if (mp[i][j] == '@' && inq[i][j] == false)
{
ans ++;
bfs(i, j);
}
}
}
}
int main()
{
const char endl = '\n';
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> m >> n)
{
if (m == 0) break;
ans = 0;
memset(mp, 0x00, sizeof(mp));
memset(inq, 0x00, sizeof(inq));
for (int i = 0; i < m ; i ++)
{
for (int j = 0; j < n; j ++)
cin >> mp[i][j];
}
bfs2();
cout << ans << endl;
}
return 0;
}
本节课课后练习题
本节课答疑
建议大家有问题先通过AI答疑(比如:DeepSeek 等),AI时代需要学会使用AI辅助学习
陈远龙老师视频讲解:如何使用DeepSeek进行答疑?
通过AI未能获得满意解答的,可以联系陈远龙老师答疑
目录