Is Topological Order (25 分)【清奇思路,不同寻常】(第十三周编程实验)

6-1 Is Topological Order (25 分)
Write a program to test if a give sequence Seq is a topological order of a given graph Graph.

Format of functions:
bool IsTopSeq( LGraph Graph, Vertex Seq[] );
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 function IsTopSeq must return true if Seq does correspond to a topological order; otherwise return false.

Note: Although the vertices are numbered from 1 to MaxVertexNum, they are indexed from 0 in the LGraph structure.

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 1 to MaxVertexNum */

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 IsTopSeq( LGraph Graph, Vertex Seq[] );

int main()
{
int i, j, N;
Vertex Seq[MaxVertexNum];
LGraph G = ReadG();
scanf("%d", &N);
for (i=0; i<N; i++) {
for (j=0; jNv; j++)
scanf("%d", &Seq[j]);
if ( IsTopSeq(G, Seq)==true ) printf(“yes\n”);
else printf(“no\n”);
}
return 0;
}

/* Your function will be put here */

Sample Input (for the graph shown in the figure):
topord.JPG

6 8
1 2
1 3
5 2
5 4
2 3
2 6
3 4
6 4
5
1 5 2 3 6 4
5 1 2 6 3 4
5 1 2 3 6 4
5 2 1 6 3 4
1 2 3 4 5 6
Sample Output:
yes
yes
yes
no
no

我的看法

这道题有两个地方需要注意,有一个地方没想到,所以我半个上午都没有做出这道题目。
1.题目自己已经提醒的坑——从0开始。我简单的把结论告诉你:
除了输入数据是从1开始的,数据一旦输入,所有的序列包括下标,包括索引,包括点的名字,通通变成了从0开始。(这估计就是read函数干的好事),所以在输入的时候,直接将数组通通减掉1,直接都按0开始做,不用考虑起点数字了。
2.也是困扰我半天,最后看了一下网上找到的唯一代码(这道题好难找啊)用队列入队出队做
但是我觉得这道题这么做很麻烦,完全不用计算入度这些,他代码写了38行,我写了24行。
但是他理解了题意,我没理解,我是看了他的代码才理解题的firstedge的。
firstedge指向的是邻接表的第二个元素——从他代码中对于入度的统计部分看出来的,稍微改了一下我的代码,我才对了。

他的思路:遍历图,统计所有的点的入度数,然后将案例入队,出队的时候判断入度数是不是0,不是0,就直接返回false。

我的思路:遍历邻接链表,如果每一层的后面的节点在样例中出现在层数数字前面,直接返回false。

AC代码,自以为比他简单:

bool LeftPre(Vertex a,Vertex b,Vertex Seq[],LGraph Graph){
    int left,right;
    for(int i=0;i<Graph->Nv;i++){
        if(a==Seq[i])left=i;
        else if(b==Seq[i])right=i;
    }
    if(left<right)return 1;
    else return 0;
}
bool IsTopSeq( LGraph Graph, Vertex Seq[] ){
     Vertex a[MaxVertexNum];
     for(int i=0;i<Graph->Nv;i++){
         a[i]=Seq[i]-1;
     }
    for(int floor=0;floor<Graph->Nv;floor++){
        PtrToAdjVNode p=Graph->G[floor].FirstEdge;
        while(p!=NULL){
            if(!LeftPre(floor,p->AdjV,a,Graph))
                return 0;
            p=p->Next;
        }
    }
            return 1;
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值