UVA - 208 Firetruck(回溯)

本文介绍了一个算法,用于解决消防站到火灾现场的最优路径选择问题。该算法接收城市街道地图和火灾位置作为输入,输出所有可能的不重复经过任意街角的路径。通过从目标点逆向搜索并进行适当的排序,确保了输出路径的正确性和效率。


 Firetruck 

The Center City fire department collaborates with the transportation department to maintain maps of the city which reflects the current status of the city streets. On any given day, several streets are closed for repairs or construction. Firefighters need to be able to select routes from the firestations to fires that do not use closed streets.

Central City is divided into non-overlapping fire districts, each containing a single firestation. When a fire is reported, a central dispatcher alerts the firestation of the district where the fire is located and gives a list of possible routes from the firestation to the fire. You must write a program that the central dispatcher can use to generate routes from the district firestations to the fires.

Input

The city has a separate map for each fire district. Streetcorners of each map are identified by positive integers less than 21, with the firestation always on corner #1. The input file contains several test cases representing different fires in different districts.

  • The first line of a test case consists of a single integer which is the number of the streetcorner closest to the fire.
  • The next several lines consist of pairs of positive integers separated by blanks which are the adjacent streetcorners of open streets. (For example, if the pair 4 7 is on a line in the file, then the street between streetcorners 4 and 7 is open. There are no other streetcorners between 4 and 7 on that section of the street.)
  • The final line of each test case consists of a pair of 0's.

Output

For each test case, your output must identify the case by number (CASE #1CASE #2, etc). It must list each route on a separate line, with the streetcorners written in the order in which they appear on the route. And it must give the total number routes from firestation to the fire. Include only routes which do not pass through any streetcorner more than once. (For obvious reasons, the fire department doesn't want its trucks driving around in circles.)

Output from separate cases must appear on separate lines.

The following sample input and corresponding correct output represents two test cases.

Sample Input

6
1 2
1 3
3 4
3 5
4 6
5 6
2 3
2 4
0 0
4
2 3
3 4
5 1
1 6
7 8
8 9
2 5
5 7
3 1
1 8
4 6
6 9
0 0

Sample Output

CASE 1:
1 2 3 4 6
1 2 3 5 6
1 2 4 3 5 6
1 2 4 6
1 3 2 4 6
1 3 4 6
1 3 5 6
There are 7 routes from the firestation to streetcorner 6.
CASE 2:
1 3 2 5 7 8 9 6 4
1 3 4
1 5 2 3 4
1 5 7 8 9 6 4
1 6 4
1 6 9 8 7 5 2 3 4
1 8 7 5 2 3 4
1 8 9 6 4
There are 8 routes from the firestation to streetcorner 4.


题目大意:输入一个n(n<=20)个节点的无向图以及某个节点k,按照字典序从小到大的顺序输出从节点1到节点k的所有路径,要求节点不能重复。

解析:从节点1往节点n查找可能会超时,所以我的想法是从节点n往节点1查找,然后用一个字符串逆序保存,但是数组保存完是逆序的字典序列,再将字符串排序,就能按照字典序输出了。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int N = 22;
const int MAX = 1000;
int edge[N][N];
bool vis[N];
int road[N];
int n;
int cnt,p;
char str[MAX][N];

int cmp(const void *a,const void *b) {
	return strcmp((char *)a,(char *)b);
}

void dfs(int u,int p) {
	if(u == 1) {
		for(int i = p -1,j = 0; i >= 0; i-- , j++) {
			str[cnt][j] = road[i] + '0';
		}
		str[cnt][p] = '\0';
		cnt++;
		return ;
	}
	for(int i = 1; i <= N; i++) {
		if(edge[u][i] && !vis[i]) {
			vis[i] = true;
			road[p] = i;
			dfs(i,p+1);
			vis[i] = false;
		}
	}
}
int main() {
	int u,v;
	int cas = 1;
	while( scanf("%d",&n) != EOF) {
		memset(edge,0,sizeof(edge));
		memset(vis,0,sizeof(vis));
		while(1) {
			scanf("%d%d",&u,&v);
			if( !u && !v) {
				break;
			}
			edge[u][v] = edge[v][u] = 1;
		}
		printf("CASE %d:\n",cas++);
		cnt = 0;
		p = 1;
		road[0] = n;
		vis[n] = true;
		dfs(n,1);
		qsort(str,cnt,sizeof(str[0]),cmp);
		for(int i = 0; i < cnt; i++) {
			int len =  strlen(str[i]);
			for(int j = 0;j < len-1; j++) {
				printf("%d ",str[i][j] - '0');
			}
			printf("%d\n",str[i][len-1] - '0');
		}
		printf("There are %d routes from the firestation to streetcorner %d.\n",cnt,n);
	}
	return 0;
}

<think>我们正在处理关于Mermaid类继承关系图的问。根据用户提供的引用内容,我们可以总结出以下几个关键点: 1. Mermaid支持类图的绘制,包括类、属性、方法以及类之间的关系(引用[1][3])。 2. 引用[2]展示了一个具体的继承关系Mermaid流程图示例:车辆类作为基类,卡车类继承车辆类,然后怪物卡车类、消防车类和自卸卡车类继承卡车类。 3. 引用[3]详细列出了类图的几种关系:关联、依赖、实现、继承、聚合、组合。 4. 引用[4]提供了一段C++递归代码,用于打印类继承关系(父类到子类的关系),并提到可以用于生成Mermaid图。 用户明确表示:“我想查找mermaid类继承关系图的相关内容”。因此,我们需要重点介绍如何使用Mermaid绘制类继承关系图。 ### 回答结构: 1. **Mermaid类图简介**:简要介绍Mermaid及其在类图绘制中的应用。 2. **类继承关系图的语法**:重点讲解如何用Mermaid表示继承关系(包括示例)。 3. **其他类关系**:由于继承是类关系的一种,我们也可以简要提及其他关系(如组合、聚合等)以便用户全面了解,但重点在继承。 4. **在Typora中使用Mermaid**:因为引用[1]提到Typora,可以简单说明如何在Typora中绘制。 5. **代码生成Mermaid图**:根据引用[4]提到的代码,说明如何从代码中生成类继承关系图(可选,但用户可能感兴趣)。 6. **示例**:给出一个完整的Mermaid类继承关系图示例。 7. **注意事项**:使用Mermaid绘制类图时的一些技巧和常见问。 ### 注意事项: - 使用中文回答。 - 引用标识放在引用内容的末尾(如[^1])。 - 生成相关问。 ### 具体回答内容: --- ### Mermaid类继承关系图详解 #### 1. Mermaid类图简介 Mermaid是一种基于文本的图表绘制工具,它使用简单的语法来描述各种图表,包括流程图、时序图、类图等[^1]。在类图中,我们可以定义类、类的成员(属性和方法)以及类之间的关系(如继承、组合等)。通过Mermaid,我们可以轻松地在文档(如Typora)中嵌入类图,方便展示对象的结构和关系。 #### 2. 类继承关系表示法 在Mermaid中,**继承关系**(也称为泛化关系)用带空心三角箭头的实线表示,箭头从子类指向父类。语法为: ``` 子类 --|> 父类 ``` 例如,有一个`Vehicle`(车辆)类,`Car`(小汽车)类继承自`Vehicle`,则可以表示为: ```mermaid classDiagram Vehicle <|-- Car ``` #### 3. 多级继承示例 引用[2]提供了一个车辆类继承关系的例子: ```mermaid classDiagram class Vehicle class Truck class MonsterTruck class FireTruck class DumpTruck Vehicle <|-- Truck Truck <|-- MonsterTruck Truck <|-- FireTruck Truck <|-- DumpTruck ``` #### 4. 类定义语法 在绘制继承关系时,我们也可以定义类的属性和方法。例如: ```mermaid classDiagram class Animal { +String name +int age +void eat() } class Dog { +void bark() } Animal <|-- Dog ``` 这里: - `+`表示`public`(公有)成员 - `-`表示`private`(私有)成员 - `#`表示`protected`(保护)成员 #### 5. 其他类关系(简要) 除了继承,Mermaid还支持以下关系[^3]: - **关联**(Association):`类1 --> 类2`(实线箭头) - **依赖**(Dependency):`类1 ..> 类2`(虚线箭头) - **实现**(Realization):`类1 ..|> 类2`(虚线空心三角箭头) - **聚合**(Aggregation):`类1 --o 类2`(空心菱形箭头) - **组合**(Composition):`类1 --* 类2`(实心菱形箭头) #### 6. 在Typora中使用Mermaid 在Typora中,你可以直接插入代码块并选择语言为`mermaid`,然后编写Mermaid类图语法即可渲染出类图[^1]。例如: ```` ```mermaid classDiagram Animal <|-- Dog Animal <|-- Cat ``` ```` #### 7. 从代码生成Mermaid类图 引用[4]展示了一段递归打印类继承关系的代码,我们可以利用类似思路生成Mermaid图。例如,通过解析代码中的类继承关系,生成对应的Mermaid语法字符串。伪代码思路: ```python # 假设我们有一个类继承关系的列表 relationships = [ {'parent': 'Vehicle', 'child': 'Truck'}, {'parent': 'Truck', 'child': 'MonsterTruck'}, # ... 其他关系 ] # 生成Mermaid字符串 mermaid_code = "classDiagram\n" for rel in relationships: mermaid_code += f" {rel['parent']} <|-- {rel['child']}\n" print(mermaid_code) ``` #### 8. 完整示例 以下是一个包含多个类和继承关系的Mermaid类图示例: ```mermaid classDiagram class Shape { <<interface>> +draw() void } class Circle { -radius: double +getArea() double } class Rectangle { -width: double -height: double } Shape <|.. Circle // Circle实现了Shape接口 Shape <|.. Rectangle // Rectangle实现了Shape接口 class Vehicle { +startEngine() void } class Car { +drive() void } class ElectricCar { +batteryLevel: int } Vehicle <|-- Car Car <|-- ElectricCar ``` #### 9. 注意事项 - 在Mermaid中,类名、属性名和方法名均不支持空格(可用下划线代替或使用双引号包裹,如`"My Class"`)。 - 默认情况下,继承关系箭头是从子类指向父类。 - 可使用`classDef`定义类样式(如引用[2]中的样式定义)。 --- ### 相关问 §§相关问§§ 1. Mermaid类图中如何表示接口和实现关系? 2. 除了继承,Mermaid类图还能表示哪些类关系? 3. 如何在Typora中调整Mermaid类图的样式? 4. 如何从C++/Java/Python代码自动生成Mermaid类图? 5. Mermaid类图支持哪些类型的成员修饰符(public、private等)? [^1]: Typora结合Mermaid可以用来绘制类图,这是非常适合在文档中展示对象关系和结构的。 [^2]: 以下是继承关系的 mermaid 流程图。 [^3]: 使用mermaid绘制类图关系。 [^4]: 为代码中的类继承关系生成Mermaid图。 </think>### Mermaid类继承关系图详解 Mermaid是一种轻量级的图表描述语言,特别适合在文档中绘制类继承关系图。以下是核心知识点: #### 1. **基本继承关系语法** 使用空心三角箭头表示继承关系(泛化关系),语法为: ```mermaid classDiagram ParentClass <|-- ChildClass ``` - `ParentClass`:父类名称 - `ChildClass`:子类名称 - `<|--`:继承关系符号(箭头指向父类) > 示例:车辆继承体系[^2] ```mermaid classDiagram Vehicle <|-- Truck Truck <|-- MonsterTruck Truck <|-- FireTruck ``` #### 2. **多级继承表示** 支持任意深度的继承链: ```mermaid classDiagram Animal <|-- Mammal Mammal <|-- Carnivore Carnivore <|-- Lion ``` #### 3. **类成员定义** 可在类中声明属性和方法: ````markdown ```mermaid classDiagram class Shape { <<interface>> +draw() void } class Circle { -radius: double +getArea() double } Shape <|.. Circle // 实现关系 ``` ```` - `+`:public成员 - `-`:private成员 - `<<interface>>`:接口标识 - `<|..`:实现关系符号 #### 4. **样式自定义** 使用`classDef`定义样式: ```mermaid classDiagram classDef base fill:#E5F6FF,stroke:#73A6FF class Vehicle:::base class Truck:::base Vehicle <|-- Truck ``` #### 5. **代码生成类图** 引用[4]展示了从代码自动生成类图的方法: ```cpp // C++示例:递归打印继承关系 void PrintParent(vector<ClassRelationship>& list, string child) { for (auto& rel : list) { if (rel.child == child) { cout << rel.parent << "-->" << rel.child << endl; PrintParent(list, rel.parent); // 递归查找父类 } } } ``` > 此方法可遍历类关系列表生成Mermaid语法[^4] #### 6. **复杂关系综合示例** ```mermaid classDiagram class Engine { +start() void } class Vehicle { +move() void } class Car { -model: string } class ElectricCar { +batteryLevel: int } Engine --* Vehicle // 组合关系 Vehicle <|-- Car Car <|-- ElectricCar ``` #### 7. **在Typora中的使用** 1. 创建代码块:```` ```mermaid ```` 2. 编写类图语法 3. Typora自动渲染为矢量图[^1] > 优势:修改文本即可更新图表,无需切换工具 #### 8. **最佳实践建议** 1. **命名规范**:类名使用帕斯卡命名法`MyClass` 2. **关系注释**:用`//`添加关系说明 3. **布局优化**: ```mermaid classDiagram direction BT // 箭头方向(bottom-top) A <|-- B A <|-- C ``` 4. **复杂图拆分**:多个小图比单个大图更清晰 ### 完整应用示例 ````markdown ```mermaid classDiagram class Shape { <<abstract>> +color: string +getArea()* double } class Circle { -radius: double +getArea() double } class Rectangle { -width: double -height: double } Shape <|-- Circle Shape <|-- Rectangle ``` ```` 渲染效果: ```mermaid classDiagram class Shape { <<abstract>> +color: string +getArea()* double } class Circle { -radius: double +getArea() double } class Rectangle { -width: double -height: double } Shape <|-- Circle Shape <|-- Rectangle ``` > 通过Mermaid可以高效创建和维护类图文档,特别适合技术文档和代码注释[^1][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值