描述
有若干个连续编号的服务,服务之间有依赖关系,启动指定的服务,判断该服务是否可以启动,如果可以,则输出依赖的前置服务编号。
Leecode描述:现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。
输入
2
1
1,1
1,0
第一行:一共有2个服务器
第二行:指定服务器的编号1
第三行:1,1表明服务器0依赖一个前置服务,依赖的服务编号为1
第四行:1,0表示服务器1依赖一个前置服务,依赖的服务编号为0
输出
-1
广度优先遍历
使用一个队列来进行广度优先搜索。开始时,所有入度为0的节点都被放入队列中,他们可以作为拓扑排序最前面的节点。所有与它相关的节点入度减一,若等于0,则放入队列中。直至队列为空,循环执行完毕。
要点1:输入是带,的需要将输入读进字符串中,再循环取出来。(stringstream,getline(),getchar())
要点2: 需要定义一个二维数组edges来存储有向图,二维数组大小为服务个数(课程多少),每个子数组存储指向的节点,例如a[0] = {1,2,3},表示执行服务2,3,4需要先执行服务0。
要点2: 定义一个一维数组indeg存储每个节点的度,首先寻找度为0的节点,弹出该节点后,根据索引在edges找出该节点的后续节点,然后再返回indeg节点,将对应的度减一。
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
int main() {
int numCourses;
cin >> numCourses;
int begin;
cin >> begin;
//清除换行符
getchar();
vector<vector<int>> prerequisites;
//将字符串转去掉逗号后,转换为数组
for (int i = 0; i < numCourses; i++) {
string str;
getline(cin,str);
stringstream ss(str);
string s;
vector<int> temp1;
while (getline(ss, s, ',')) {
int a = stoi(s);
temp1.push_back(stoi(s));
}
//转化为课程表问题,具体参考Leecode
for (int j = 1; j < temp1.size(); j++) {
prerequisites.push_back({ i,temp1[j] });
}
}
//存储课程的学习顺序
vector<int> path;
//存储有向图
vector<vector<int>>edges;
//存储节点的度
vector<int>indeg;
indeg.resize(numCourses);
edges.resize(numCourses);
queue<int> q;
//根据有向图存储节点的度
for (int i = 0; i < prerequisites.size(); i++) {
vector<int>temp = prerequisites[i];
indeg[temp[0]]++;
edges[temp[1]].push_back(temp[0]);
}
//选定入度为0的顶点入队列.
for (int i = 0; i < numCourses; i++) {
if (indeg[i] == 0) {
q.push(i);
}
}
//进入循环.
while (!q.empty()) {
int cur = q.front();
q.pop();
path.push_back(cur);
//将队列头作为弧起点的弧去掉,弧终点对应的入度--,如果入度为0,加入队列.
for (int i = 0; i < edges[cur].size(); i++) {
int tail = edges[cur][i];
indeg[tail]--;
if (indeg[tail] == 0) {
q.push(tail);
}
}
}
//根据上课顺序,打印需要的节点
vector<int> ans;
if (path.size() == numCourses) {
for (int i = 0; i < numCourses; i++) {
if (path[i] == begin){
for (int k = 0; k<ans.size()-1; k++) {
cout << ans[k] << ',';
}
cout << ans[ans.size() - 1];
return 0;
}
ans.push_back(path[i]);
}
}
cout << -1 << endl;
return 0;
}