Topological Sort (25分)

Write a program to find the topological order in a digraph.

Format of functions:

bool TopSort( LGraph Graph, Vertex TopOrder[] );

where LGraph is defined as the following:

typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
    Vertex AdjV;
    PtrToAdjVNode Next;
};

typedef struct Vnode{
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

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

The topological order is supposed to be stored in TopOrder[] where TopOrder[i] is the i-th vertex in the resulting sequence. The topological sort cannot be successful if there is a cycle in the graph -- in that case TopSort must return false; otherwise return true.

Notice that the topological order might not be unique, but the judge‘s input guarantees the uniqueness of the result.

Sample program of judge:

#include <stdio.h>
#include <stdlib.h>

typedef enum {false, true} bool;
#define MaxVertexNum 10  /* maximum number of vertices */
typedef int Vertex;      /* vertices are numbered from 0 to MaxVertexNum-1 */

typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
    Vertex AdjV;
    PtrToAdjVNode Next;
};

typedef struct Vnode{
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

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

LGraph ReadG(); /* details omitted */

bool TopSort( LGraph Graph, Vertex TopOrder[] );

int main()
{
    int i;
    Vertex TopOrder[MaxVertexNum];
    LGraph G = ReadG();

    if ( TopSort(G, TopOrder)==true )
        for ( i=0; i<G->Nv; i++ )
            printf("%d ", TopOrder[i]);
    else
        printf("ERROR");
    printf("\n");

    return 0;
}

/* Your function will be put here */

Sample Input 1 (for the graph shown in the figure):

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

Sample Output 1:

4 3 2 1 0 

Sample Input 2 (for the graph shown in the figure):

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

Sample Output 2:

ERROR

第一版的代码没有过,是因为超时,原因是我写了一个O(V^2)的算法,这道题必须要使用O(V+E)的算法。

int Incoming[MaxVertexNum];
int Queue[MaxVertexNum], head = 0, tail = 0;

bool FindNextIncomingZero(LGraph Graph) {
    for (int i = 0; i < Graph->Nv; i++) {
        if (!Incoming[i]) Queue[tail++] = i, Incoming[i]--;
    }
}

bool TopSort(LGraph Graph, Vertex TopOrder[]) {
    for (int i = 0; i < Graph->Nv; i++) {
        for (PtrToAdjVNode ptr = Graph->G[i].FirstEdge; ptr != NULL; ptr = ptr->Next) {
            Incoming[ptr->AdjV]++;
        }
    }

    FindNextIncomingZero(Graph);
    int temp = 0;
    while (head < tail) {
        TopOrder[temp++] = Queue[head++];
        for (PtrToAdjVNode ptr = Graph->G[Queue[head - 1]].FirstEdge; ptr != NULL; ptr = ptr->Next) {
            Incoming[ptr->AdjV]--;
        }
        FindNextIncomingZero(Graph);
    }

    return temp==Graph->Nv;
}

注意到其实在第一版的代码中FindNextIncomingZero这个函数是多余的,完全可以把这个函数合并到while循环中,这样就好了:

int Incoming[MaxVertexNum];
int Queue[MaxVertexNum], head = 0, tail = 0;

bool TopSort( LGraph Graph, Vertex TopOrder[] ){
    for(int i=0;i<Graph->Nv;i++)
        for(PtrToAdjVNode ptr = Graph->G[i].FirstEdge;ptr!=NULL;ptr = ptr->Next)
            Incoming[ptr->AdjV]++;

    for(int i=0;i<Graph->Nv;i++)
        if(!Incoming[i]) Queue[tail++] = i,Incoming[i]--;

    int temp=0;
    while(head<tail){
        TopOrder[temp++]=Queue[head++];
        for(PtrToAdjVNode ptr = Graph->G[Queue[head-1]].FirstEdge;ptr!=NULL;ptr = ptr->Next)
            if(!--Incoming[ptr->AdjV]) Queue[tail++] = ptr->AdjV,Incoming[ptr->AdjV]--;
    }

    if(temp!=Graph->Nv) return false;
    return true;
}

原文地址:https://www.cnblogs.com/nonlinearthink/p/12173517.html

时间: 2024-08-01 07:28:41

Topological Sort (25分)的相关文章

PTA 09-排序3 Insertion or Heap Sort (25分)

题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/676 5-14 Insertion or Heap Sort   (25分) According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion s

1098 Insertion or Heap Sort (25 分)

According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted li

【PAT甲级】1098 Insertion or Heap Sort (25 分)

题意: 输入一个正整数N(<=100),接着输入两行N个数,表示原数组和经过一定次数排序后的数组.判断是经过插入排序还是堆排序并输出再次经过该排序后的数组(数据保证答案唯一). AAAAAccepted code: 1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 int a[107],b[107]; 5 int c[107][5]; 6 int main(){ 7 ios:

【PAT甲级】1101 Quick Sort (25 分)

题意: 输入一个正整数N(<=1e5),接着输入一行N个各不相同的正整数.输出可以作为快速排序枢纽点的个数并升序输出这些点的值. trick: 测试点2格式错误原因:当答案为0时,需要换行两次??.....这是为何 AAAAAccepted code: 1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 int a[100007]; 5 int b[100007]; 6 int

PAT甲级——1146 Topological Order (25分)

This is a problem given in the Graduate Entrance Exam in 2018: Which of the following is NOT a topological order obtained from the given directed graph? Now you are supposed to write a program to test each of the options. Input Specification: Each in

A1098 Insertion or Heap Sort (25分)

一.技术总结 这是一道考查插入排序和堆排序的问题. 这里开始最主要的问题是,没有理解堆排序.堆排序是通过把数组中第一个元素与最后一个元素交换,然后再对于第一个元素进行向下调整downAdjust函数. 所以这里对于插入排序,只要一直遍历发现第一个元素的比前一个元素小,记录下这时的下标.然后同时后面的元素与原数组相同,那么就是插入排序. 对于堆排序怎么知道到哪一步,根据堆排序的特点知道.是通过从后往前交换元素,然后使用downAdjust函数调整,所以要判断,就从后往前判断,如果出现当前元素,比首

PTA 10-排序6 Sort with Swap(0, i) (25分)

题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/678 5-16 Sort with Swap(0, i)   (25分) Given any permutation of the numbers {0, 1, 2,..., N-1N?1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is

1146 Topological Order (25 分)判断拓扑序列

1146 Topological Order (25 分) This is a problem given in the Graduate Entrance Exam in 2018: Which of the following is NOT a topological order obtained from the given directed graph? Now you are supposed to write a program to test each of the options

1101 Quick Sort (25 分)递推

1101 Quick Sort (25 分) There is a classical process named partition in the famous quick sort algorithm. In this process we typically choose one element as the pivot. Then the elements less than the pivot are moved to its left and those larger than th