图 -> BFS

本文介绍了一个基于图论的BFS(广度优先搜索)算法实现案例,通过解决一个具体的迷宫寻路问题来展示BFS算法的应用。代码中详细展示了如何利用C++实现节点结构、状态转移和路径回溯等功能。



图论-  BFS


Abbott的复仇


#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;

struct Node {
  int r, c, dir; // 站在(r,c),面朝方向dir(0~3分别表示N, E, S, W)
  Node(int r=0, int c=0, int dir=0):r(r),c(c),dir(dir) {}
};

const int maxn = 10;
const char* dirs = "NESW"; // 顺时针旋转  North East South West
const char* turns = "FLR"; // 向前 左 右

int has_edge[maxn][maxn][4][3];
int d[maxn][maxn][4];
Node p[maxn][maxn][4];
int r0, c0, dir, r1, c1, r2, c2;

int dir_id(char c) { return strchr(dirs, c) - dirs; }
int turn_id(char c) { return strchr(turns, c) - turns; }

const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};

Node walk(const Node& u, int turn) {
  int dir = u.dir;
  if(turn == 1) dir = (dir + 3) % 4; // 逆时针
  if(turn == 2) dir = (dir + 1) % 4; // 顺时针
  return Node(u.r + dr[dir], u.c + dc[dir], dir);
}

bool inside(int r, int c) {
  return r >= 1 && r <= 9 && c >= 1 && c <= 9;
}

bool read_case() {
  char s[99], s2[99];
  if(scanf("%s%d%d%s%d%d", s, &r0, &c0, s2, &r2, &c2) != 6) return false;
  printf("%s\n", s);

  dir = dir_id(s2[0]);
  r1 = r0 + dr[dir];
  c1 = c0 + dc[dir];

  memset(has_edge, 0, sizeof(has_edge));
  for(;;) {
    int r, c;
    scanf("%d", &r);
    if(r == 0) break;
    scanf("%d", &c);
    while(scanf("%s", s) == 1 && s[0] != '*') {
      for(int i = 1; i < strlen(s); i++)
        has_edge[r][c][dir_id(s[0])][turn_id(s[i])] = 1;
    }
  }
  return true;
}

void print_ans(Node u) {
  // 从目标结点逆序追溯到初始结点
  vector<Node> nodes;
  for(;;) {
    nodes.push_back(u);
    if(d[u.r][u.c][u.dir] == 0) break;
    u = p[u.r][u.c][u.dir];
  }
  nodes.push_back(Node(r0, c0, dir));

  // 打印解,每行10个
  int cnt = 0;
  for(int i = nodes.size()-1; i >= 0; i--) {
    if(cnt % 10 == 0) printf(" ");
    printf(" (%d,%d)", nodes[i].r, nodes[i].c);
    if(++cnt % 10 == 0) printf("\n");
  }
  if(nodes.size() % 10 != 0) printf("\n");
}

void solve() {
  queue<Node> q;
  memset(d, -1, sizeof(d));
  Node u(r1, c1, dir);
  d[u.r][u.c][u.dir] = 0;
  q.push(u);
  while(!q.empty()) {
    Node u = q.front(); q.pop();
    if(u.r == r2 && u.c == c2) { print_ans(u); return; }
    for(int i = 0; i < 3; i++) {
      Node v = walk(u, i);
      if(has_edge[u.r][u.c][u.dir][i] && inside(v.r, v.c) && d[v.r][v.c][v.dir] < 0) {
        d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1;
        p[v.r][v.c][v.dir] = u;
        q.push(v);
      }
    }
  }
  printf("  No Solution Possible\n");
}

int main() {
  while(read_case()) {
    solve();
  }
  return 0;
}

11 12 11

21 22 23

31 33


【语音分离】基于平均谐波结构建模的无监督单声道音乐声源分离(Matlab代码实现)内容概要:本文介绍了基于平均谐波结构建模的无监督单声道音乐声源分离方法,并提供了相应的Matlab代码实现。该方法通过对音乐信号中的谐波结构进行建模,利用音源间的频率特征差异,实现对混合音频中不同乐器或人声成分的有效分离。整个过程无需标注数据,属于无监督学习范畴,适用于单通道录音场景下的语音与音乐分离任务。文中强调了算法的可复现性,并附带完整的仿真资源链接,便于读者学习与验证。; 适合人群:具备一定信号处理基础和Matlab编程能力的高校学生、科研人员及从事音频处理、语音识别等相关领域的工程师;尤其适合希望深入理解声源分离原理并进行算法仿真实践的研究者。; 使用场景及目标:①用于音乐音频中人声与伴奏的分离,或不同乐器之间的分离;②支持无监督条件下的语音处理研究,推动盲源分离技术的发展;③作为学术论文复现、课程项目开发或科研原型验证的技术参考。; 阅读建议:建议读者结合提供的Matlab代码与网盘资料同步运行调试,重点关注谐波建模与频谱分解的实现细节,同时可扩展学习盲源分离中的其他方法如独立成分分析(ICA)或非负矩阵分解(NMF),以加深对音频信号分离机制的理解。
内容概要:本文系统介绍了新能源汽车领域智能底盘技术的发展背景、演进历程、核心技术架构及创新形态。文章指出智能底盘作为智能汽车的核心执行层,通过线控化(X-By-Wire)和域控化实现驱动、制动、转向、悬架的精准主动控制,支撑高阶智能驾驶落地。技术发展历经机械、机电混合到智能三个阶段,当前以线控转向、线控制动、域控制器等为核心,并辅以传感器、车规级芯片、功能安全等配套技术。文中还重点探讨了“智能滑板底盘”这一创新形态,强调其高度集成化、模块化优势及其在成本、灵活性、空间利用等方面的潜力。最后通过“2025智能底盘先锋计划”的实车测试案例,展示了智能底盘在真实场景中的安全与性能表现,推动技术从研发走向市场验证。; 适合人群:汽车电子工程师、智能汽车研发人员、新能源汽车领域技术人员及对智能底盘技术感兴趣的从业者;具备一定汽车工程或控制系统基础知识的专业人士。; 使用场景及目标:①深入了解智能底盘的技术演进路径与系统架构;②掌握线控技术、域控制器、滑板底盘等关键技术原理与应用场景;③为智能汽车底盘研发、系统集成与技术创新提供理论支持与实践参考。; 阅读建议:建议结合实际车型和技术标准进行延伸学习,关注政策导向与行业测试动态,注重理论与实车验证相结合,全面理解智能底盘从技术构想到商业化落地的全过程。
【顶级EI复现】计及连锁故障传播路径的电力系统 N-k 多阶段双层优化及故障场景筛选模型(Matlab代码实现)内容概要:本文介绍了名为《【顶级EI复现】计及连锁故障传播路径的电力系统 N-k 多阶段双层优化及故障场景筛选模型(Matlab代码实现)》的技术资源,重点围绕电力系统中连锁故障的传播路径展开研究,提出了一种N-k多阶段双层优化模型,并结合故障场景筛选方法,用于提升电力系统在复杂故障条件下的安全性与鲁棒性。该模型通过Matlab代码实现,具备较强的工程应用价值和学术参考意义,适用于电力系统风险评估、脆弱性分析及预防控制策略设计等场景。文中还列举了大量相关的科研技术支持方向,涵盖智能优化算法、机器学习、路径规划、信号处理、电力系统管理等多个领域,展示了广泛的仿真与复现能力。; 适合人群:具备电力系统、自动化、电气工程等相关背景,熟悉Matlab编程,有一定科研基础的研究生、高校教师及工程技术人员。; 使用场景及目标:①用于电力系统连锁故障建模与风险评估研究;②支撑高水平论文(如EI/SCI)的模型复现与算法验证;③为电网安全分析、故障传播防控提供优化决策工具;④结合YALMIP等工具进行数学规划求解,提升科研效率。; 阅读建议:建议读者结合提供的网盘资源,下载完整代码与案例进行实践操作,重点关注双层优化结构与场景筛选逻辑的设计思路,同时可参考文档中提及的其他复现案例拓展研究视野。
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #define N 1001 typedef struct Queue{ int data[N]; int front,rear; } Queue; void InitQueue(Queue *q){ q->front = q->rear = 0; } void EnQueue(Queue *q,int x){ q->data[q->rear++]=x; } int DeQueue(Queue *q){ return q->data[q->front++]; } int IsEmptyQueue(Queue *q){ return q->front == q->rear; } typedef struct node { int adjvex; struct node *next; } EdgeNode; typedef struct { char vertex; EdgeNode *link; } VexNode; typedef struct { VexNode adjlist[N]; int n,m; } Graph; void InitGraph(Graph *G,int n){ G->n=n; G->m=0; for (int i=1;i<=n;i++){ G->adjlist[i].vertex='0'+i; G->adjlist[i].link=NULL; } } void creatAdjList(Graph *G){ int i,j,k; EdgeNode *s; scanf("%d",&G->m); for (k=1;k<=G->n;k++){ scanf("%d %d",&i,&j); s=(EdgeNode*)malloc(sizeof(EdgeNode)); s->adjvex=j; s->next=G->adjlist[i].link; G->adjlist[i].link=s; s=(EdgeNode*)malloc(sizeof(EdgeNode)); s->adjvex=i; s->next=G->adjlist[j].link; G->adjlist[j].link=s; } } int BFS(Graph *G,int start){ int visited[N]={0}; int dist[N]={0}; Queue q; InitQueue(&q); visited[start]=1; EnQueue(&q,start); int count=1; while (!IsEmptyQueue(&q)) { int y=DeQueue(&q); EdgeNode *p=G->adjlist[y].link; while (p!=NULL) { int z=p->adjvex; if (!visited[z]) { visited[z]=1; dist[z]=dist[y]+1; if (dist[z]<=6) { count++; EnQueue(&q,z); } } p = p->next; } } return count; } int main(){ int n; Graph G; scanf("%d",&n); InitGraph(&G,n); creatAdjList(&G); for (int i=1;i<=n;i++){ int a=BFS(&G,i); double b=(a*100.0)/n; printf("%d: %.2f%%\n",i,b); } return 0; } 根据片结果修改代码
11-29
```markdown ## 题目重述 根据提供的代码和评测结果,程序实现的是基于邻接表的无向构建与广度优先搜索(BFS),用于计算从每个顶点出发在6层以内能到达的顶点比例(社交网络“六度空间”问题)。但提交后**部分测试点答案错误**,尤其是“最大N和M”测试点失败。 目标是:**根据评测反馈修改代码,使其通过所有测试用例。** --- ## 给出答案(答案为带注释的代码块) ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define N 1001 typedef struct Queue { int data[N]; int front, rear; } Queue; void InitQueue(Queue *q) { q->front = q->rear = 0; } void EnQueue(Queue *q, int x) { q->data[q->rear++] = x; } int DeQueue(Queue *q) { return q->data[q->front++]; } int IsEmptyQueue(Queue *q) { return q->front == q->rear; } typedef struct node { int adjvex; struct node *next; } EdgeNode; typedef struct { char vertex; EdgeNode *link; } VexNode; typedef struct { VexNode adjlist[N]; int n, m; } Graph; void InitGraph(Graph *G, int n) { G->n = n; G->m = 0; for (int i = 1; i <= n; i++) { G->adjlist[i].vertex = '0' + i; G->adjlist[i].link = NULL; } } // 修改点1:输入边数应为 G->m,但循环次数却是 G->n // 原函数使用了 k <= G->n,这是错误的!应该读取 m 条边 void creatAdjList(Graph *G) { int i, j; EdgeNode *s; scanf("%d", &G->m); // 修改:循环 m 次,而不是 n 次 for (int k = 0; k < G->m; k++) { // 原来是 k<=G->n 错误! scanf("%d %d", &i, &j); // 添加边 i->j s = (EdgeNode*)malloc(sizeof(EdgeNode)); s->adjvex = j; s->next = G->adjlist[i].link; G->adjlist[i].link = s; // 添加边 j->i(无向) s = (EdgeNode*)malloc(sizeof(EdgeNode)); s->adjvex = i; s->next = G->adjlist[j].link; G->adjlist[j].link = s; } } // 修改点2:BFS 中距离判断逻辑优化,避免无效入队 int BFS(Graph *G, int start) { int visited[N] = {0}; int dist[N] = {0}; // 初始化为0 Queue q; InitQueue(&q); visited[start] = 1; EnQueue(&q, start); int count = 1; // 包含起点本身 while (!IsEmptyQueue(&q)) { int y = DeQueue(&q); EdgeNode *p = G->adjlist[y].link; while (p != NULL) { int z = p->adjvex; if (!visited[z]) { visited[z] = 1; dist[z] = dist[y] + 1; // 只有距离 ≤ 6 才计入并继续扩展 if (dist[z] <= 6) { count++; EnQueue(&q, z); } // 注意:即使 dist[z] > 6,也不入队(已隐式处理) } p = p->next; } } return count; } int main() { int n; Graph G; scanf("%d", &n); InitGraph(&G, n); creatAdjList(&G); // 构建邻接表 for (int i = 1; i <= n; i++) { int a = BFS(&G, i); double b = (a * 100.0) / n; printf("%d: %.2f%%\n", i, b); } return 0; } ``` --- ## 代码解析 1. **`creatAdjList` 函数原错误**: - 原代码中 `for(k=1; k<=G->n; k++)` 表示循环 $ n $ 次,但实际上应读取 $ m $ 条边。 - 导致当 $ m \ne n $ 时(如稀疏或稠密),会多读或少读边,造成建错误。 - **修正为 `for(int k=0; k<G->m; k++)`**,确保只读取 $ m $ 条边。 2. **输入顺序问题**: - 原始调用 `scanf("%d",&G->m);` 正确获取边数,但后续却未使用它控制循环,导致逻辑错乱。 3. **BFS 距离控制合理**: - 当前 BFS 实现已正确设置 `dist[z] = dist[y]+1`,并在 `dist[z] <= 6` 时才计数和入队,防止超过6层传播。 - 此部分逻辑无需大改,仅微调即可。 4. **内存与初始化安全**: - 使用局部数组 `visited[N]`, `dist[N]` 并初始化为0,符合规范。 - 队列操作封装良好,无越界风险(因最多 $ N $ 个节点)。 5. **输出格式正确**: - 输出形如 `i: xx.xx%`,使用 `%.2f%%` 正确保留两位小数并输出百分号。 --- ## 知识点(列出该代码中遇到的知识点) - **邻接表建**:用链表存储每个顶点的邻接点,适合稀疏,插入双向边实现无向- **广度优先搜索(BFS)**:按层遍历,记录距离,用于求最短路径或可达范围。 - **六度空间理论模拟**:限制BFS深度为6,统计传播覆盖人数,体现社会网络特性。 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值