算法分析与设计课程作业第五周#1

算法分析与设计课程作业第五周#1

这周选择一道图论的medium题目来做,题目是一个经典的排课问题,主要是考察判断一个有向图有无环的。
以下是题目:

207. Course Schedule

There are a total of n courses you have to take, labeled from 0 to n - 1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
Note:
1.The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
2.You may assume that there are no duplicate edges in the input prerequisites.

思路

算法课上已经讲过怎么判断一个图有无环了,就是深度优先搜索遍历图,根据得到的各个点pre值与post值是否满足某条边(u,v)上两点pre[v]<=pre[u]<post[u]<=post[v],若满足,则图存在前向边(回边),即图中存在环。明白这些后,解决问题就没难度了。在这之前我实现图都是使用邻接矩阵,这次就尝试下使用邻接表。
顺便还学习了下pair的用法:
1.构造:
pair<int, double> p0(1, 2.4);  
2.访问两个元素(通过first和second):
pair<int, double> p1;  //使用默认构造函数
p1.first = 3;
p1.second = 3.6;
3.利用make_pair和赋值operator = 赋值:
pair<int, double> p2;
p2 = make_pair(1, 1.8);
大致就这么多。

代码

这次没有出什么错误,打完就过了,就直接上正确代码了。

class Solution {
public:
    void traverse(vector<int> edge[], int vertice, int pre[], int post[], int &time, bool found[]){
        ++time;
        pre[vertice] = time;
        found[vertice] = true;
        vector<int> ::iterator iter;
        for(iter = edge[vertice].begin(); iter != edge[vertice].end(); iter++){
            if(!found[*iter]){
                traverse(edge, *iter, pre, post, time, found);
            }
        }
        ++time;
        post[vertice] = time;
    }
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<int> edge[numCourses];
        int pre[numCourses];
        int post[numCourses];
        int time = 0;
        bool found[numCourses];
        for(int j = 0; j < numCourses; j++){
            found[j] = false;
        }
        vector<pair<int, int>> ::iterator i = prerequisites.begin();
        for( ; i != prerequisites.end(); i++){
            edge[i->second].push_back(i->first);
        }
        for(int j = 0; j < numCourses; j++){
            if(!found[j]){
                traverse(edge, j, pre, post, time, found);
            }
        }
        for(int j = 0; j < numCourses; j++){
            vector<int> ::iterator iter;
            for(iter = edge[j].begin(); iter != edge[j].end(); iter++){
                if(pre[*iter] <= pre[j] && post[j] <= post[*iter]) return false;
            }
        }
        return true;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值