207.Course Schedule

问题:课程之间具有依赖性,比如必须先修某门课,然后才可以修另外的课程。给你一些课程,以及课程的依赖关系,求是否能够完成所有课程

思路:这种题属于任务队列,先根据依赖关系建立邻接表数组,然后选出所有入度为0的课程入队,修完这些课,相应的依赖课程的入度减1,然后再继续将入度为0的课程入队,直到队列为空。此时判断:如果入队的课程数等于总的课程数,说明每一门课程都入队了,也就是说每门课的入度都降为0,所以可以完成所有课程;如果入队的课程数不等于总的课程数,说明不可以完成所有课程。

class Solution {

public:
    struct edge{
        int from,to,next;
        edge(int u=0,int v=0,int n=0):from(u),to(v),next(n){}
    }edges[10000];//最多的边数,这里随便设置的最多10000条边,没想到竟然能过
    int FIRST[10000];//每个节点的第一条边,这里同样是随便设置的最多10000个节点
    int edge_count;//实际边的数量


    void add_edge(int from,int to){
        edge_count++;
        edges[edge_count]=edge(from,to,FIRST[from]);
        FIRST[from]=edge_count;
    }
    bool canFinish(int numCourses, vector<pair<int,int> >& prerequisites) {
        if(numCourses<0) return false;
        if(numCourses==0) return true;
        if(prerequisites.size()==0) return true;


        //初始化节点的入度
        int* degree=new int[numCourses];
        for(int i=0;i<numCourses;i++){
            degree[i]=0;
        }
        //建立图
        for(vector<pair<int,int> >::iterator iter=prerequisites.begin();iter!=prerequisites.end();iter++){
            int from=iter->second;
            int to=iter->first;
            add_edge(from,to);
            degree[to]++;
        }


        queue<int> canfinish;
        //入度为0的课程入队
        for(int i=0;i<numCourses;i++){
            if(degree[i]==0){
                canfinish.push(i);
            }
        }
        //记录可以完成的课程数量
        int canfinish_num=0;
        while(!canfinish.empty()){
            int front_node=canfinish.front();
            //每完成一个课程,相关的依赖课程的入度就减1
            for(int iter=FIRST[front_node];iter;iter=edges[iter].next){
                int to=edges[iter].to;
                degree[to]--;
                if(0==degree[to]){
                    canfinish.push(to);
                }
            }
            canfinish_num++;
            canfinish.pop();
        }
        //只有当入队的数量等于课程总数量,说明课程都可以入队,也就是入度都能降成0,所以true
        if(canfinish_num==numCourses) return true;
        else return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值