Algoritmo 6.10-6.11 Camino más corto 6.12 Clasificación topológica 6.13 Camino crítico 6.14 Espacio de seis dimensiones

Un estudiante universitario desconocido, conocido como Caigou en el mundo de las artes marciales.
Autor original: Jacky Li
. Correo electrónico: [email protected].

Hora de finalización: 2022.12.10
Última edición: 2022.12.11

84fa9f28ca0e4c8d9e2464a5fc6288c1.jpeg

Tabla de contenido

Algoritmo 6.10-6.11 Camino más corto

Nivel 1: Algoritmo 6.10 Camino más corto de Dijkstra

detalles de la misión

información relacionada

Requisitos de programación

Instrucciones de entrada y salida

Instrucción de prueba

Código de referencia

Nivel 2: Algoritmo 6.11 Floyd

detalles de la misión

información relacionada

Requisitos de programación

Instrucciones de entrada y salida

Instrucción de prueba

Código de referencia

Algoritmo 6.12 Clasificación topológica

detalles de la misión

Requisitos de programación

Instrucciones de entrada y salida

Código de referencia

6.13 Camino crítico

detalles de la misión

Requisitos de programación

Instrucciones de entrada y salida

Código de referencia

6.14 Seis dimensiones del espacio

detalles de la misión

Requisitos de programación

Instrucciones de entrada y salida

Código de referencia

El autor tiene algo que decir.


 

Algoritmo 6.10-6.11 Camino más corto

Nivel 1: Algoritmo 6.10 Camino más corto de Dijkstra

detalles de la misión

La tarea de este nivel: escribir un algoritmo de Dijkstra para el camino más corto y usar una matriz de adyacencia para representar el gráfico.

información relacionada

Para completar esta tarea, necesita dominar: 1. Cómo crear una matriz de adyacencia 2. Cómo escribir Dijkstra.

Requisitos de programación

Siga las instrucciones y agregue código en el editor de la derecha para generar la ruta más corta correspondiente a los dos vértices.

Instrucciones de entrada y salida

Instrucciones de entrada: La primera línea es el número de vértices n y el número de aristas e. La segunda línea son n símbolos de vértices. La siguiente línea e son aristas e. Los primeros dos caracteres de cada línea representan un borde del gráfico no dirigido, y el tercero representa el peso del borde. Los dos vértices de la última fila representan el punto inicial y el punto final.

Descripción de salida: camino más corto entre vértices

Instrucción de prueba

La plataforma probará el código que escribas:

Entrada de prueba:

6 10

a B C D e F

ab 6

CA 5

anuncio 1

disco 5

cama 5

ser 3

de 6

efecto 6

df 4

ver 2

af

Salida de prueba:

a-->d

c-->f

b-->e

d-->f

b-->d

a-->d-->f

Código de referencia

//算法6.8 普里姆算法
#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
#include <cstring>

#define IOS std::ios::sync_with_stdio(false)
//#define YES cout << "1"
//#define NO cout << "0"
#define MaxInt 0x3f
#define MVNum 100
#define OK 1
#define ERROR -1

const int N = 1003;

using namespace std;
typedef long long LL;

typedef char VerTexType;
typedef int ArcType;

int *D=new int[MVNum];	                    				//用于记录最短路的长度
bool *S=new bool[MVNum];          							//标记顶点是否进入S集合
int *Path=new int[MVNum];									//用于记录最短路顶点的前驱

//------------图的邻接矩阵-----------------
typedef struct{ 
	VerTexType vexs[MVNum];            						//顶点表 
	ArcType arcs[MVNum][MVNum];      						//邻接矩阵 
	int vexnum,arcnum;                						//图的当前点数和边数 
}AMGraph;

int LocateVex(AMGraph G , VerTexType v){
	//确定点v在G中的位置
	for(int i = 0; i < G.vexnum; ++i)
		if(G.vexs[i] == v)
			return i;
   return -1;
}//LocateVex

void CreateUDN(AMGraph &G){ 
    //采用邻接矩阵表示法,创建无向网G 
	int i , j , k;
    cin >> G.vexnum >> G.arcnum;							//输入总顶点数,总边数

    for(i = 0; i < G.vexnum; ++i)  
		cin >> G.vexs[i];                        			//依次输入点的信息 
	

    for(i = 0; i < G.vexnum; ++i)                			//初始化邻接矩阵,边的权值均置为极大值MaxInt 
		for(j = 0; j < G.vexnum; ++j)   
			G.arcs[i][j] = MaxInt; 

	for(k = 0; k < G.arcnum;++k)
	{							//构造邻接矩阵 
		VerTexType v1 , v2;
		ArcType w;

		cin >> v1 >> v2 >> w;								//输入一条边依附的顶点及权值
		i = LocateVex(G, v1);  j = LocateVex(G, v2);		//确定v1和v2在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;									//边<v1, v2>的权值置为w 
		G.arcs[j][i] = G.arcs[i][j];						//置<v1, v2>的对称边<v2, v1>的权值为w 
	}//for
}//CreateUDN

void ShortestPath_DIJ(AMGraph G, int v0){ 
    //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径 
    /*************************Begin***********************/
	int v,w,minn;
	int n=G.vexnum;
	for( v=0;v<n;v++)
	{
		S[v]=false;
		D[v]=G.arcs[v0][v];
		if(D[v]<MaxInt) Path[v]=v0;
		else Path[v]=-1;
	}

	S[v0]=true; D[v0]=0;

	for(int i=1;i<n;i++)
	{
		minn=MaxInt;
		for( w=0;w<n;w++)
			if(!S[w])
				if(D[w]<minn)
			v = w, minn = D[w];
		
		if(minn<MaxInt)
		{
			S[v]=true;
			for( w=0;w<n;w++)
				if(!S[w]&&(minn+G.arcs[v][w]<D[w]))
					D[w] = minn + G.arcs[v][w], Path[w] = v;
		}
		else break;
	}
}//ShortestPath_DIJ

void DisplayPath(AMGraph G , int begin ,int temp ){
	//显示最短路
	if(Path[temp] != -1){
		DisplayPath(G , begin ,Path[temp]);
		cout << G.vexs[Path[temp]] << "-->";
	}
}//DisplayPath

int main()
{
	
	AMGraph G; 
	int num_start , num_destination;
	VerTexType start , destination;
	CreateUDN(G);

	cin >> start >> destination;
	num_start = LocateVex(G , start);
	num_destination = LocateVex(G , destination);
	ShortestPath_DIJ(G , num_start);

	DisplayPath(G , num_start , num_destination);
	cout << G.vexs[num_destination]<<endl;
	
	return 0;
}//main

 

Nivel 2: Algoritmo 6.11 Floyd

detalles de la misión

La tarea de este nivel: escribir un algoritmo Floy para el camino más corto y usar una matriz de adyacencia para representar el gráfico.

información relacionada

Para completar esta tarea, necesita dominar: 1. Cómo crear una matriz de adyacencia 2. Cómo escribir Floyd.

Requisitos de programación

Siga las instrucciones y agregue código en el editor de la derecha para generar la ruta más corta correspondiente a los dos vértices.

Instrucciones de entrada y salida

Instrucciones de entrada: La primera línea es el número de vértices n y el número de aristas e. La segunda línea son n símbolos de vértices. La siguiente línea e son aristas e. Los primeros dos caracteres de cada línea representan un borde del gráfico no dirigido, y el tercero representa el peso del borde. Los dos vértices de la última fila representan el punto inicial y el punto final.

Descripción de salida: camino más corto entre vértices

Instrucción de prueba

La plataforma probará el código que escribas:

Entrada de prueba:

6 10

a B C D e F

ab 6

CA 5

anuncio 1

disco 5

cama 5

ser 3

de 6

efecto 6

df 4

ver 2

af

Salida de prueba:

a-->d-->f

La longitud del camino más corto es:

5

Código de referencia

//算法6.8 普里姆算法
#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
#include <cstring>

#define IOS std::ios::sync_with_stdio(false)
//#define YES cout << "1"
//#define NO cout << "0"
#define MaxInt 0x3f
#define MVNum 100
#define OK 1
#define ERROR -1

const int N = 1003;

using namespace std;
typedef long long LL;

typedef char VerTexType;
typedef int ArcType;

int Path[MVNum][MVNum];						//最短路径上顶点vj的前一顶点的序号
int D[MVNum][MVNum];						//记录顶点vi和vj之间的最短路径长度

//------------图的邻接矩阵---------------
typedef struct{ 
	VerTexType vexs[MVNum];            		//顶点表 
	ArcType arcs[MVNum][MVNum];      		//邻接矩阵 
	int vexnum,arcnum;                		//图的当前点数和边数 
}AMGraph;

int LocateVex(AMGraph G , VerTexType v){
	//确定点v在G中的位置
	for(int i = 0; i < G.vexnum; ++i)
		if(G.vexs[i] == v)
			return i;
		return -1;
}//LocateVex

void CreateUDN(AMGraph &G){ 
    //采用邻接矩阵表示法,创建有向网G 
	int i , j , k;
    cin >> G.vexnum >> G.arcnum;							//输入总顶点数,总边数

    for(i = 0; i < G.vexnum; ++i)   
		cin >> G.vexs[i];                        			//依次输入点的信息 
	

    for(i = 0; i < G.vexnum; ++i)   //初始化邻接矩阵,边的权值均置为极大值MaxInt 
		for(j = 0; j < G.vexnum; ++j)
			if(j != i) G.arcs[i][j] = MaxInt;  
			else G.arcs[i][j] = 0;

	for(k = 0; k < G.arcnum; ++ k)
	{						//构造邻接矩阵 
		VerTexType v1 , v2;
		ArcType w;
		cin >> v1 >> v2 >> w;                           //输入一条边依附的顶点及权值
		i = LocateVex(G, v1);  j = LocateVex(G, v2);	//确定v1和v2在G中的位置,即顶点数组的下标 
		G.arcs[i][j] = w;								//边<v1, v2>的权值置为w 
	}//for
}//CreateUDN 

void ShortestPath_Floyed(AMGraph G)
{ 
    //用Floyd算法求有向网G中各对顶点i和j之间的最短路径 
	int i, j, k;
	for(i = 0; i < G.vexnum; i ++)
	for(j = 0; j < G.vexnum; j ++)
	{
		D[i][j] = G.arcs[i][j];
		if((D[i][j] < MaxInt) && (i != j))  Path[i][j] = i;
		else  Path[i][j] = -1;  
	}
	for(k = 0; k < G.vexnum; k ++)
		for(i = 0; i < G.vexnum; i ++)
			for(j = 0; j < G.vexnum; j ++)
				if(D[i][k] + D[k][j] < D[i][j])
					D[i][j] = D[i][k] + D[k][j], Path[i][j] = Path[k][j];
}//ShortestPath_Floyed

void DisplayPath(AMGraph G , int begin ,int temp )
{
	if(Path[begin][temp] != -1)
	{
		DisplayPath(G , begin ,Path[begin][temp]);
		cout << G.vexs[Path[begin][temp]] << "-->";
	}
}//DisplayPath

int main(){

	AMGraph G;
	char start , destination;
	int num_start , num_destination;

	CreateUDN(G);
	
	ShortestPath_Floyed(G);

	cin >> start >> destination;
	num_start = LocateVex(G , start);
	num_destination = LocateVex(G , destination);

	DisplayPath(G , num_start , num_destination);
	cout << G.vexs[num_destination] << endl;
	cout << "最短路径的长度为:" << D[num_start][num_destination] << endl;
	cout <<endl;
	
	return 0;
}//main

Algoritmo 6.12 Clasificación topológica

detalles de la misión

La tarea de este nivel: generar la secuencia de clasificación topológica del gráfico dirigido.

Requisitos de programación

Siga las indicaciones y agregue código en el editor de la derecha para calcular y generar la clasificación topológica del gráfico dirigido.

Instrucciones de entrada y salida

Entrada : La primera línea es el número de vértices ny arcos e, separados por espacios. La segunda línea es nel nombre del símbolo del vértice, separado por espacios. La siguiente elínea es cada arco, separado por espacios.

Salida : Si no hay un bucle en la red, genera la secuencia de clasificación topológica separada por comas. De lo contrario, muestra "¡Hay un bucle en la red y no se puede realizar la clasificación topológica!"

Entrada de prueba:

3 3

1 2 3

1 2

1 3

2 3

Rendimiento esperado:

1, 2, 3

Código de referencia

#include <iostream>
using namespace std;

#define MVNum 100                       	//最大顶点数
#define OK 1	
#define ERROR 0 

typedef char VerTexType;

//- - - - -图的邻接表存储表示- - - - - 
typedef struct ArcNode{                		//边结点 
    int adjvex;                          	//该边所指向的顶点的位置 
    struct ArcNode *nextarc;          		//指向下一条边的指针 
}ArcNode; 

typedef struct VNode{ 
    VerTexType data;                    	//顶点信息 
    ArcNode *firstarc;                		//指向第一条依附该顶点的边的指针 
}VNode, AdjList[MVNum];               		//AdjList表示邻接表类型 

typedef struct{ 
    AdjList vertices;                 		//邻接表 
	AdjList converse_vertices;				//逆邻接表
    int vexnum, arcnum;              		//图的当前顶点数和边数 
}ALGraph;
//- - - - - - - - - - - - - - - -

//- - - - -顺序栈的定义- - - - -
typedef struct{
	int *base;
	int *top;
	int stacksize;
}spStack;
//- - - - - - - - - - - - - - - -

int indegree[MVNum];						//数组indegree存放个顶点的入度
spStack S;

//------------栈的相关操作----------------------
void InitStack(spStack &S){
	//初始化栈
	S.base = new int[MVNum];
	if(!S.base)
		exit(1);
	S.top = S.base;
	S.stacksize = MVNum;
}//InitStack

void Push(spStack &S , int i){
	//进栈
	if(S.top - S.base == S.stacksize)
		return;
	*S.top++ = i;
}//Push

void Pop(spStack &S , int &i){
	//出栈
	if(S.top == S.base)
		return;
	i = *--S.top;
}//Pop

bool StackEmpty(spStack S){
	//判断栈是否为空
	if(S.top == S.base)
		return true;
	return false;
}//StackEmpty
//-------------------------------------------------

int LocateVex(ALGraph G , VerTexType v){
	//确定点v在G中的位置
	for(int i = 0; i < G.vexnum; ++i)
		if(G.vertices[i].data == v)
			return i;
		return -1;
}//LocateVex

int CreateUDG(ALGraph &G){ 
	//创建有向图G的邻接表、逆邻接表
	int i , k;
	cin >> G.vexnum >> G.arcnum;				//输入总顶点数,总边数 
	for(i = 0; i < G.vexnum; ++i){          	//输入各点,构造表头结点表
	
		cin >> G.vertices[i].data;           	//输入顶点值
		G.converse_vertices[i].data = G.vertices[i].data;
		//初始化表头结点的指针域为NULL 
		G.vertices[i].firstarc=NULL;			
		G.converse_vertices[i].firstarc=NULL;
    }//for
	
	for(k = 0; k < G.arcnum;++k){        		//输入各边,构造邻接表
		VerTexType v1 , v2;
		int i , j;
		cin >> v1 >> v2;                		//输入一条边依附的两个顶点
		i = LocateVex(G, v1);  j = LocateVex(G, v2);
		//确定v1和v2在G中位置,即顶点在G.vertices中的序号 

		ArcNode *p1=new ArcNode;               	//生成一个新的边结点*p1 
		p1->adjvex=j;                   		//邻接点序号为j
		p1->nextarc = G.vertices[i].firstarc;  G.vertices[i].firstarc=p1;
		//将新结点*p1插入顶点vi的边表头部

		ArcNode *p2=new ArcNode;               	//生成一个新的边结点*p1 
		p2->adjvex=i;                   		//逆邻接点序号为i
		p2->nextarc = G.converse_vertices[j].firstarc;  G.converse_vertices[j].firstarc=p2;
		//将新结点*p1插入顶点vi的边表头部
    }//for 
    return OK; 
}//CreateUDG

void FindInDegree(ALGraph G){
	//求出各顶点的入度存入数组indegree中 
/******************************Begin***********************/
for(int i=0; i<G.vexnum; i++) {
		int cnt = 0;
		while(G.converse_vertices[i].firstarc != NULL) {
			cnt++;
			G.converse_vertices[i].firstarc = G.converse_vertices[i].firstarc->nextarc;
		}
		indegree[i] = cnt;
	}


/******************************End*************************/
	
}//FindInDegree

int TopologicalSort(ALGraph G , int topo[]){ 
    //有向图G采用邻接表存储结构 
    //若G无回路,则生成G的一个拓扑序列topo[]并返回OK,否则ERROR 
/******************************Begin***********************/
FindInDegree(G);
int i,m=0;
ArcNode *p;

InitStack(S);
for(i=0;i<G.vexnum;i++)
if(!indegree[i])  Push(S,i);
while(!StackEmpty(S)){
	Pop(S,i);  topo[m]=i; m++;
	for(p=G.vertices[i].firstarc;p;p=p->nextarc)
	{
		int k=p->adjvex;
		if(!(--indegree[k]))  Push(S,k);
	}
}

if(m<G.vexnum) return 0; else return 1;


/******************************End*************************/
}//TopologicalSort 

int main(){
	
	ALGraph G;
	CreateUDG(G);
	int *topo = new int [G.vexnum];
	


	if(TopologicalSort(G , topo)){
		for(int j = 0 ; j < G.vexnum; j++){
			if(j != G.vexnum - 1)
				cout << G.vertices[topo[j]].data << " , ";
			else
				cout << G.vertices[topo[j]].data << endl << endl;
		}//for
	}
	else
		cout << "网中存在环,无法进行拓扑排序!" <<endl;
	return OK;
}//main

6.13 Camino crítico

detalles de la misión

La tarea de este nivel: generar la ruta crítica de la red.

Requisitos de programación

Siga las indicaciones y agregue código en el editor de la derecha para calcular la ruta crítica de la red.

Instrucciones de entrada y salida

Entrada: La primera línea es el número de vértices ny arcos e, separados por espacios. La segunda línea es nel nombre del símbolo del vértice, separado por espacios. La siguiente elínea es cada arco y su peso, separados por espacios.

Salida: si no hay un bucle en la red, genere la ruta crítica, de lo contrario, muestre "¡Hay un bucle en la red y no se puede realizar la clasificación topológica!"

Entrada de prueba:

3 3

1 2 3

1 2 5

1 3 6

2 3 1

Rendimiento esperado:

1-->3

1-->2

2-->3

Código de referencia

//算法6.13 关键路径算法

#include <iostream>
using namespace std;

#define MVNum 100                       	//最大顶点数
#define BDNum MVNum * (MVNum - 1)			//最大边数
#define OK 1	
#define ERROR 0 

typedef char VerTexType;

//- - - - -图的邻接表存储表示- - - - - 
typedef struct ArcNode{                		//边结点 
    int adjvex;                          	//该边所指向的顶点的位置
	int weight;								//权值
    struct ArcNode *nextarc;          		//指向下一条边的指针 
}ArcNode; 

typedef struct VNode{ 
    VerTexType data;                    	//顶点信息
    ArcNode *firstarc;                		//指向第一条依附该顶点的边的指针 
}VNode, AdjList[MVNum];               		//AdjList表示邻接表类型 

typedef struct{ 
    AdjList vertices;                 		//邻接表 
	AdjList converse_vertices;				//逆邻接表
    int vexnum, arcnum;              		//图的当前顶点数和边数 
}ALGraph;
//- - - - - - - - - - - - - - - -

//- - - - -顺序栈的定义- - - - -
typedef struct{
	int *base;
	int *top;
	int stacksize;
}spStack;
//- - - - - - - - - - - - - - - -

int indegree[MVNum];						//数组indegree存放个顶点的入度
int ve[BDNum];								//事件vi的最早发生时间
int vl[BDNum];								//事件vi的最迟发生时间
int topo[MVNum];							//记录拓扑序列的顶点序号
spStack S;

//----------------栈的操作--------------------
void InitStack(spStack &S){
	//栈的初始化
	S.base = new int[MVNum];
	if(!S.base)
		exit(1);
	S.top = S.base;
	S.stacksize = MVNum;
}//InitStack

void Push(spStack &S , int i){
	//入栈
	if(S.top - S.base == S.stacksize)
		return;
	*S.top++ = i;
}//Push

void Pop(spStack &S , int &i){
	//出栈
	if(S.top == S.base)
		return;
	i = *--S.top;
}//Pop

bool StackEmpty(spStack S){
	//判断栈是否为空
	if(S.top == S.base)
		return true;
	return false;
}//StackEmpty
//---------------------------------------

int LocateVex(ALGraph G , VerTexType v){
	//确定点v在G中的位置
	for(int i = 0; i < G.vexnum; ++i)
		if(G.vertices[i].data == v)
			return i;
		return -1;
}//LocateVex

int CreateUDG(ALGraph &G){ 
	//创建有向图G的邻接表、逆邻接表
	int i , k;
	cin >> G.vexnum >> G.arcnum;				//输入总顶点数,总边数 
	for(i = 0; i < G.vexnum; ++i){          		//输入各点,构造表头结点表
		cin >> G.vertices[i].data;           		//输入顶点值
		G.converse_vertices[i].data = G.vertices[i].data;
		//初始化表头结点的指针域为NULL 
		G.vertices[i].firstarc=NULL;			
		G.converse_vertices[i].firstarc=NULL;
    }//for
	for(k = 0; k < G.arcnum;++k){        			//输入各边,构造邻接表
		VerTexType v1 , v2;
		int i , j , w;
		cin >> v1 >> v2 >> w;                		//输入一条边依附的两个顶点
		i = LocateVex(G, v1);  j = LocateVex(G, v2);
		//确定v1和v2在G中位置,即顶点在G.vertices中的序号 

		ArcNode *p1=new ArcNode;               		//生成一个新的边结点*p1 
		p1->adjvex=j;                   			//邻接点序号为j
		p1->nextarc = G.vertices[i].firstarc;  G.vertices[i].firstarc=p1;
		p1->weight = w;
		//将新结点*p1插入顶点vi的边表头部

		ArcNode *p2=new ArcNode;               		//生成一个新的边结点*p1 
		p2->adjvex=i;                   			//逆邻接点序号为i
		p2->nextarc = G.converse_vertices[j].firstarc;  G.converse_vertices[j].firstarc=p2;
		p2->weight = w;
		//将新结点*p1插入顶点vi的边表头部
    }//for 
    return OK; 
}//CreateUDG

void FindInDegree(ALGraph G){
	//求出各顶点的入度存入数组indegree中 
	int i , count;

	for(i = 0 ; i < G.vexnum ; i++){
		count = 0;
		ArcNode *p = G.converse_vertices[i].firstarc;
		if(p){
			while(p){
				p = p->nextarc;
				count++;
			}
		}//if
		indegree[i] = count;
	}//for
}//FindInDegree

int TopologicalOrder(ALGraph G , int topo[]){ 
    //有向图G采用邻接表存储结构 
    //若G无回路,则生成G的一个拓扑序列topo[]并返回OK,否则ERROR 
	int i , m;
    FindInDegree(G);              				//求出各顶点的入度存入数组indegree中 
    InitStack(S);                          		//栈S初始化为空 
    for(i = 0; i < G.vexnum; ++i)
		if(!indegree[i]) Push(S, i);     		//入度为0者进栈 
	m = 0;                               		//对输出顶点计数,初始为0 
	while(!StackEmpty(S)){                		//栈S非空 
		Pop(S, i);                          	//将栈顶顶点vi出栈
		topo[m]=i;                         		//将vi保存在拓扑序列数组topo中 
		++m;                             		//对输出顶点计数 
		ArcNode *p = G.vertices[i].firstarc;    //p指向vi的第一个邻接点 
		while(p){
			int k = p->adjvex;					//vk为vi的邻接点   
			--indegree[k];                   	//vi的每个邻接点的入度减1 
			if(indegree[k] ==0)  Push(S, k);	//若入度减为0,则入栈 
			p = p->nextarc;                		//p指向顶点vi下一个邻接结点 
		}//while 
	}//while
	
	if(m < G.vexnum)  return ERROR;    			//该有向图有回路 
	else return OK;
}//TopologicalOrder
int i,k,e,l,j;
int CriticalPath(ALGraph G){ 
    //G为邻接表存储的有向网,输出G的各项关键活动
int i,k,j;
ArcNode *p;
//G为邻接表存储的有向网,输出G的各项关键活动
	if (!TopologicalOrder(G, topo)) return ERROR;
	//调用拓扑排序算法,使拓扑序列保存在topo中,若调用失败,则存在有向环
	int n = G.vexnum;			//n为顶点的个数
	for (i = 0;i < n;i++)			//给每个事件的最早发生时间置初值为0
		ve[i] = 0;
	/*按照拓扑次序求每个事件的最早发生时间*/
	for (i = 0;i < n;i++)			//for循环结束才能求得最早发生时间
	{
		k = topo[i];			//取得拓扑序列中的顶点序号k
		p = G.vertices[k].firstarc;			//p指向k的第一个邻接点
		while (p != NULL)			//依次更新k的所有邻接顶点的最早发生时间
		{
			j = p->adjvex;			//j为邻接顶点的序号
			if (ve[j] < ve[k] + p->weight)			//更新顶点j的最早发生时间ve[j]
				ve[j] = ve[k] + p->weight;
			p = p->nextarc;			//p指向k的下一个邻接顶点
		}
	}
	for (i = 0;i < n;i++)			//给每个事件的最迟发生时间置初值为ve[n-1]
		vl[i] = ve[n - 1];
	/*按逆拓扑次序求每个事件的最迟发生时间*/
	for (i = n - 1;i >= 0;i--)
	{
		k = topo[i];			//取得拓扑序列中的顶点序号k
		ArcNode* p = G.vertices[k].firstarc;			//p指向k的第一个邻接顶点
		while (p != NULL)
		{	//根据k的邻接点,更新k的最迟发生时间
			j = p->adjvex;			//j为邻接顶点的序号
			if (vl[k] > vl[j] - p->weight)			//更新顶点k的最迟发生时间vl[k]
				vl[k] =  vl[j] - p->weight;
			p = p->nextarc;			//p指向下一个邻接顶点
		}
	}
	/*判断每一活动是否为关键活动*/
	for (i = 0;i < n;i++)
	{ //每次循环针对vi为活动开始点的所有活动
		p = G.vertices[i].firstarc;			//p指向i的第一个邻接顶点
		while (p != NULL)
		{
			j = p->adjvex;			//j为i的邻接顶点的序号
			e = ve[i];			//计算活动<vi,vj>的最早开始时间
			l = vl[j] - p->weight;			//计算活动<vi,vj>的最迟开始时间
			if (e == l)		//若为关键活动,输出<vi,vj>
				cout<<G.vertices[i].data<<"-->"<<G.vertices[j].data<<" ";
			p = p->nextarc;			//p指向i的下一个邻接顶点
		}
	}

}//CriticalPath

int main(){

	ALGraph G;
	CreateUDG(G);
	int *topo = new int [G.vexnum];
	if(!CriticalPath(G))
		cout << "网中存在环,无法进行拓扑排序!" << endl;
	cout << endl;
	return OK;
}//main

6.14 Seis dimensiones del espacio

detalles de la misión

La tarea de este nivel: verificar la teoría del espacio de seis dimensiones.

Requisitos de programación

Según las indicaciones, agregue código en el editor de la derecha para calcular el porcentaje de rutas que comienzan desde el vértice 0 y cuya longitud no excede 7.

Instrucciones de entrada y salida

Entrada: La primera línea es el número de vértices ny aristas e, separados por espacios.

  1. 接下来`$$e$$`行是每条边

Salida: El porcentaje de caminos cuya longitud de punto fijo no excede 7, representado en decimales, conservando 6 decimales.

Entrada de prueba:

10 9

0 1

1 2

2 3

3 4

4 5

5 6

6 7

7 8

8 9

Rendimiento esperado:

0.800000

Código de referencia

#include<stdio.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
vector<int> g[1003];
int n,m,num,i,visit[1003]={0};
void makeg(){	//构成临界矩阵。
	int x,y;
	for(i=0;i<m;i++){
		scanf("%d %d",&x,&y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
}
void  BFS(int x)
{	//对每个用户进行遍历。
	queue<int> q;
	q.push(x);
	visit[x] = 1, num ++;
	for(int deep = 0; deep < 7; deep ++)
    {
		vector<int> t;	//设置一个数组来静态存储当前层次待遍历用户,若用队列存储的话,需要一个当前层次队列,以及待遍历的下一层次队列,完成后涉及到队列的交替转换,难以实现。
		while(!q.empty())
        {
			int temp=q.front();
			q.pop();
			t.push_back(temp);
		}
		for(i = 0; i < t.size(); i ++)
        {
			int k = t[i];
			for(int j = 0; j < g[k].size(); j ++)
            {
				int temp = g[k][j];
				if(visit[temp]==0)
                {
					visit[temp]=1, num++;
					q.push(temp);
				}
			}
		}
	}
}
int main(){
	scanf("%d %d",&n,&m);
	makeg();
	num=0;
	fill(visit,visit+n+1,0);	//由于是1-n编号,此处要初始化到visit+n+1;
	BFS(0);
	printf("%f\n",double(num)/(double)n);
	return 0;
}

El autor tiene algo que decir.

Si cree que lo que dijo el blogger es útil para usted, haga clic en "Seguir" para apoyarlo. Continuaremos actualizando dichos problemas...

 

 

Supongo que te gusta

Origin blog.csdn.net/weixin_62075168/article/details/128268125
Recomendado
Clasificación