教学计划(拓扑排序)c++【做题记录】

【题目要求】

现在你总共有 N 门课需要选择,记为 0 到 N-1。

在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们,如:  0,1

给定课程总量,条件条数以及它们的先决条件,判断是否可能完成所有课程的学习?并两门课程的教学安排顺序是否正确?

【输入形式】

第一行,输入:课程数N,课程之间的关系数M

第二行开始,输入M行,输入课程关系(若要学习课程1,需要先完成课程2)输入:课程1,课程2

继续输入两个课程编号c1,c2.

【输出形式】

第一行输出:是否可以完成课程(true/false)

第二行输出:是否允许先安排学习课程c1在安排学习c2(true/false),如果第一行为false,则不输出第二行。

【样例输入1】

4 4

1,0

2,0

3,1

3,2

3,0

【样例输出1】

true

true

【样例说明1】

总共有 4 门课程。要学习课程 0,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 3之后。这是可能的,因此第一行输出true。

教学计划允许先安排学习课程3,再安排学习课程0,因此第二行输出true。

【样例输入2】

2 2

1,0

0,1

1,0

【样例输出2】

false

【样例说明2】

总共有 2 门课程。学习课程0之前,你还应先完成课程1;并且学习课程1之前,你需要先完成课程0。这是不可能的,因此第一行输出false。第二行不输出。

【代码】

#include<iostream>
#include<stack>
#include<cstring>
#define MAX 100
using namespace std;
typedef struct ArcNode          //边结点
{
    int adjvex;                 //顶点下标
    ArcNode* next;
} ArcNode;
typedef struct
{
    int in;                     //in是入度
    int vertex;              //顶点信息
    ArcNode* firstEdge;
} vertexNode, VertexNode[MAX];

class ALGraph
{
private:
    int vertexNum, arcNum;   //顶点数,边数
    VertexNode adjList;     //顶点数组
    stack<vertexNode> s;    //栈
    int count = 0;            //计数
    int result[MAX];        //存储拓扑排序结果的数组
public:
    ALGraph(int v[], int n, int e);
    bool TopologicalSort(); //拓扑排序
    bool isReasonable(int c1, int c2);
};
bool ALGraph::TopologicalSort()
{
    int k = 0;
    for (int i = 0; i < vertexNum; i++)  //in为0则压栈
    {
        if (adjList[i].in == 0)
        {
            s.push(adjList[i]);
        }
    }
    while (!s.empty())               //循环终止条件:栈为空
    {
        vertexNode v = s.top();       //弹栈输出
        s.pop();
        result[k++]= v.vertex;       //存放拓扑排序结果
        count++;                    //计数加一
        ArcNode* a = v.firstEdge;
        while (a)                    //对弹出的结点遍历,所有遍历过的结点的in-1
        {
            adjList[a->adjvex].in--;
            int tmp = adjList[a->adjvex].in;
            if (tmp == 0)              //如果某结点的in变为0,则将其压栈
            {
                s.push(adjList[a->adjvex]);
            }
            a = a->next;
        }
    }
    if (count < vertexNum) {
        cout << "false\n";
        return false;//如果计数小于顶点数则说明有环
    }
    else {
        cout << "true\n";
        return true;
    }
}
ALGraph::ALGraph(int v[], int n, int e)    //构造函数
{
    vertexNum = n;
    arcNum = e;
    for (int i = 0; i < vertexNum; i++)          //顶点初始化
    {
        adjList[i].in = 0;
        adjList[i].vertex = v[i];
        adjList[i].firstEdge = NULL;
        result[i] = 0;
    }
    ArcNode* s;
    int vi, vj;
    char c;
    for (int i = 0; i < arcNum; i++)
    {
        s = new ArcNode;
        cin >> vi >>c>> vj;
        s->adjvex = vj;
        s->next = adjList[vi].firstEdge;      //头插法
        adjList[vi].firstEdge = s;
        adjList[vj].in++;                   //入度加一
    }
}
//判断c1,c2的安排是否合理
bool ALGraph::isReasonable(int c1, int c2)
{
    int p1, p2;   //记录c1,c2的下标
    p1 = result[c1];
    p2 = result[c2];
    return p1 < p2 ? true : false;  //如果c1的下标小于c2,说明c1安排在c2前面,合理即返回真,否则c1应该安排在c2后面,返回假
}
int main()
{
    int n, e,c1,c2;
    bool flag;
    cin >> n >> e;
    int v[MAX];
    for (int i = 0; i < n; i++)
    {
        v[i] = i;
    }
    ALGraph algraph(v, n, e);
    flag=algraph.TopologicalSort();
    cin >> c1 >> c2;
    if (flag)
    {
        if (algraph.isReasonable(c1, c2))
            cout << "true" << endl;
        else
            cout << "false\n";
    }

    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值