C Clasificación topológica + Búsqueda de la duración total 08-Figura 8 ¿Cuánto tiempo se tarda (25 puntos)

08- 图 8 ¿Cuánto tiempo se tarda (25 分)

Dadas las relaciones de todas las actividades de un proyecto, se supone que debe encontrar el tiempo de finalización más temprano del proyecto.

Especificación de entrada:
cada archivo de entrada contiene un caso de prueba. Cada caso comienza con una línea que contiene dos enteros positivos N (≤100), el número de puntos de verificación de actividad (por lo tanto, se supone que los puntos de verificación están numerados de 0 a N − 1) y M, el número de actividades. Luego siguen las líneas M, cada una da la descripción de una actividad. Para la i-ésima actividad, se dan tres números no negativos: S [i], E [i] y L [i], donde S [i] es el índice del punto de control inicial, E [i] de el punto de control final y L [i] el tiempo duradero de la actividad. Los números en una línea están separados por un espacio.

Especificación de salida:
para cada caso de prueba, si la programación es posible, imprima en una línea el tiempo de finalización más temprano; o simplemente muestra "Imposible".

Entrada de muestra 1:

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

Salida de muestra 1:

18

Entrada de muestra 2:

4 5
0 1 1
0 2 2
2 1 3
1 3 4
3 2 5

Salida de muestra 2:

Impossible

Resolución de problemas
Dado el número de nodos, bordes y pesos de un gráfico topológico, encuentre la duración total más corta del gráfico topológico de vez en cuando;
tenga en cuenta que
los bordes del gráfico topológico son bordes unidireccionales, y preste atención a la dirección al insertar bordes; cada vez que la
clasificación topológica
encuentra el grado Si el nodo es 0, agregue el nodo a la tabla de proceso, elimine el nodo y actualice la entrada del nodo adyacente al nodo;
si es necesario calcular las horas de trabajo totales, mantenga una matriz para almacenar el final de cada nodo El tiempo de trabajo más corto, es decir, el tiempo de trabajo más corto de todos los nodos en grados de este nodo más las horas de trabajo del proceso, el valor máximo obtenido;

Debido a que hay menos bordes de clasificación topológica, la tabla de adyacencia se puede almacenar
1. Almacene los datos de entrada en la tabla de adyacencia

#include<iostream> 
#include<queue> 
#include<vector>
#define MAXN 101
using namespace std;

//邻接表储存
//要获得每个点的入度,当入度变为0时入队, 
typedef int Vertex;
typedef int WeightType;

typedef struct ENode *ptrtoENode;
struct ENode{
	Vertex V1,V2;
	WeightType Weight;
};
typedef ptrtoENode Edge;

typedef struct AdjVNode* ptrtoAdjVNode;
struct AdjVNode{
	Vertex AdjV;
	WeightType Weight;
	ptrtoAdjVNode Next;
};

typedef struct VNode{
	ptrtoAdjVNode FirstEdge;
}AdjList[MAXN];

typedef struct GNode* ptrtoGNode;
struct GNode{
	int Nv;
	int Ne;
	AdjList G;
};
typedef ptrtoGNode LGraph;

LGraph CreateGraph(int VertexNum)
{
	Vertex V;
	LGraph Graph;
	Graph= new struct GNode;
	Graph->Nv=VertexNum;
	Graph->Ne=0;
	for(V=0;V<Graph->Nv;V++)
		Graph->G[V].FirstEdge=NULL;
	return Graph;
}

void InsertEdge(LGraph Graph,Edge E)
{                                    		//拓扑图为有向图 
	ptrtoAdjVNode NewNode;
	NewNode = new struct AdjVNode;
	NewNode->AdjV = E->V2;
	NewNode->Weight=E->Weight;
	NewNode->Next=Graph->G[E->V1].FirstEdge;
	Graph->G[E->V1].FirstEdge=NewNode;
	
}

LGraph BuildGraph()
{
	LGraph Graph;
	Edge E;
	Vertex V;
	int Nv,i;
	
	cin>>Nv;
	Graph=CreateGraph(Nv);
	cin>>Graph->Ne;
	for(int i=0;i<Graph->Ne;i++)
	{
		E=new struct ENode;
		cin>>E->V1>>E->V2>>E->Weight;
		
		InsertEdge(Graph,E);
	}
	return Graph;   //别忘了返回 
}

Tenga en cuenta que una función de borde de inserción del borde dirigido inserto función, la realización de un inserto hacia adelante;
2. La función de clasificación topológica
primera inicializa la lista de grado;
para el vértice es 0 en cola , y las horas-hombre como 0 punto;
Agregar contadores cnt, cuando finaliza el bucle final, el número de vértices atravesados cnt es diferente del número total de vértices, lo que indica que el gráfico no está conectado y vuelve a impossibel;
ingrese el bucle, el número de nodo en la cola se quita, atraviesa el nodo posterior del nodo y luego el nodo Cuando el grado -1 es 0, el nodo posterior se une al equipo y compara el tiempo de trabajo del nodo posterior con (tiempo de trabajo del nodo actual + tiempo de trabajo del proceso), el que sea mayor es el tiempo de trabajo mínimo del nodo posterior;

int Earliest[MAXN];
bool TopSort( LGraph Graph, Vertex TopOrder[] )
{ /* 对Graph进行拓扑排序,  TopOrder[]顺序存储排序后的顶点下标 */
    int Indegree[MAXN], cnt;
    Vertex V;
    ptrtoAdjVNode W;       //结点W 
    queue <int>Q;
  
    /* 初始化Indegree[] */
    for (V=0; V<Graph->Nv; V++)
        Indegree[V] = 0;
         
    /* 遍历图,得到Indegree[] */
    for (V=0; V<Graph->Nv; V++)
        for (W=Graph->G[V].FirstEdge; W; W=W->Next)
            Indegree[W->AdjV]++; /* 对有向边<V, W->AdjV>累计终点的入度 */
//入度正确 	
	   
    /* 将所有入度为0的顶点入列 */
    for (V=0; V<Graph->Nv; V++)
        if ( Indegree[V]==0 )
            {
			Q.push(V);
			Earliest[V]=0;//
        }
    /* 下面进入拓扑排序 */ 
    cnt = 0; 
    while( !Q.empty()){
        V = Q.front();
		Q.pop(); /* 弹出一个入度为0的顶点 */
        TopOrder[cnt++] = V; /* 将之存为结果序列的下一个元素 */
        /* 对V的每个邻接点W->AdjV */
        for ( W=Graph->G[V].FirstEdge; W; W=W->Next )
            if ( --Indegree[W->AdjV] == 0 )/* 若删除V使得W->AdjV入度为0 */
                {
				Q.push(W->AdjV); /* 则该顶点入列 */ 
				if(Earliest[V]+W->Weight>Earliest[W->AdjV])
				Earliest[W->AdjV]=Earliest[V]+W->Weight;
				}
		} /* while结束*/
     
    if ( cnt != Graph->Nv )
        return false; /* 说明图中有回路, 返回不成功标志 */ 
    else
        return true;
}

En este momento, se ha obtenido el tiempo total de todos los nodos;
3. función principal
Debido a que puede haber más de un punto final del proceso, es necesario recorrer la lista de tiempo de trabajo y tomar el punto final de trabajo máximo como la salida de tiempo de trabajo total mínimo.

int main()
{
	LGraph Graph=BuildGraph();
	int TopOrder[MAXN];
	
	bool R=TopSort(Graph,TopOrder);
	if(!R){
		cout<<"Impossible"<<endl;
		return 0;
	}
	int Max=0;
	for(int i=0;i<Graph->Nv;i++)
		cout<<Earliest[i]<<" ";
		//if(Earliest[i]>Max)
			//Max=Earliest[Graph->Nv-1];
		//cout<<Max<<endl;
	
}
Publicados 105 artículos originales · ganado elogios 6 · vistas 4951

Supongo que te gusta

Origin blog.csdn.net/BLUEsang/article/details/105511400
Recomendado
Clasificación