11237: 【原1237】Courses
题目
题目描述
author: DS TA 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1237
Description
学生需要修读完所有的课程才能毕业,这些课程之间有先导关系(比如要修读数据结构,必须先修读程序设计思想方法)。假设任意一门课程可以在任何一个学期给满足条件的学生选修,且学生每个学期可以选修的课程数不限。先给出一些课程与课程之间的关系,求能够修完所有课程的最少学期数。
为简化题目,约定:假设有n门课程,则这n门课程的编号分别为:1,2,……n。
数据保证不会出现环和自环(即总是可以合法地修完所有的课程,不会出现类似“1->1”或是“1->2->3->1”的情况)
(提示:如果你没有很好的思路,请仔细看P360开始的“拓扑排序”部分内容。)
Input Format
第1行:n m //正整数n ,代表课程的数量。非负整数m代表要给出几个先导关系。
第2行到第1+m行: a b //每行两个整数:代表要选修编号为a的课程,必须先修读编号为b的课程。
Output Format
一个整数,即修完所有课程的最少学期数。
Sample Input1
5 4
1 2
2 3
3 4
4 5
Sample Output1
5
Sample Input2
6 0
Sample Output2
1
Sample Input3
6 3
1 2
1 3
4 1
Sample Output3
3
Limits
0<n<=10000 0<=m<=100000
数据保证合法
ligongzzz's solution
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
using pii = pair<int, int>;
class node {
public:
int remain = 0;
vector<int> child;
};
vector<node> nlist;
int bfs(const vector<int> rlist) {
queue<pii> qdata;
for(auto root:rlist)
qdata.push(make_pair(root, 1));
int ans = 0;
while (!qdata.empty()) {
auto temp = qdata.front();
qdata.pop();
ans = max(ans, temp.second);
for (auto& p : nlist[temp.first].child) {
--nlist[p].remain;
if (!nlist[p].remain) {
qdata.push(make_pair(p, temp.second + 1));
}
}
}
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
nlist.resize(n + 1);
for (; m; --m) {
int a, b;
cin >> a >> b;
++nlist[a].remain;
nlist[b].child.emplace_back(a);
}
vector<int> rlist;
for (int i = 1; i <= n; ++i) {
if (nlist[i].remain == 0)
rlist.emplace_back(i);
}
cout << bfs(rlist);
return 0;
}
Neight99's solution
#include <iostream>
using namespace std;
const int maxN = 1e5 + 100;
template <class elemType>
class seqQueue {
private:
elemType *data;
int maxSize;
int front, rear;
void doubleSpace();
public:
seqQueue(int size = maxN);
~seqQueue();
bool isEmpty() const;
void enQueue(const elemType &);
elemType deQueue();
elemType getHead() const;
int length() const;
};
template <class elemType>
void seqQueue<elemType>::doubleSpace() {
elemType *tmp = data;
data = new elemType[maxSize * 2];
for (int i = 1; i <= maxSize; i++) {
data[i] = tmp[(front + i) % maxSize];
}
front = 0;
rear = maxSize;
maxSize *= 2;
delete[] tmp;
}
template <class elemType>
seqQueue<elemType>::seqQueue(int size) : maxSize(size), front(0), rear(0) {
data = new elemType[size];
}
template <class elemType>
seqQueue<elemType>::~seqQueue() {
delete[] data;
}
template <class elemType>
bool seqQueue<elemType>::isEmpty() const {
return front == rear;
}
template <class elemType>
void seqQueue<elemType>::enQueue(const elemType &x) {
// if ((rear + 1) % maxSize == front) {
// doubleSpace();
// }
rear = (rear + 1) % maxSize;
data[rear] = x;
}
template <class elemType>
elemType seqQueue<elemType>::deQueue() {
front = (front + 1) % maxSize;
return data[front];
}
template <class elemType>
elemType seqQueue<elemType>::getHead() const {
return data[(front + 1) % maxSize];
}
template <class elemType>
int seqQueue<elemType>::length() const {
return ((rear + maxSize - front) % maxSize);
}
struct edgeNode {
int data;
edgeNode *next;
edgeNode(int d = 0, edgeNode *n = 0) : data(d), next(n) {}
};
struct verNode {
int data;
int times;
edgeNode *head;
verNode(int d = 0, edgeNode *h = 0) : data(d), times(0), head(h) {}
};
int n, m, temp1, temp2, ans = 0, inDegree[maxN] = {0};
verNode *nodes[maxN];
seqQueue<int> que;
void topSort();
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
nodes[i] = new verNode(i);
}
for (int i = 0; i < m; i++) {
cin >> temp1 >> temp2;
nodes[temp2]->head = new edgeNode(temp1, nodes[temp2]->head);
}
topSort();
for (int i = 1; i <= n; i++) {
ans = (nodes[i]->times > ans) ? nodes[i]->times : ans;
}
cout << ans;
return 0;
}
void topSort() {
edgeNode *p;
int current;
for (int i = 1; i <= n; i++) {
for (p = nodes[i]->head; p; p = p->next) {
inDegree[p->data]++;
}
}
for (int i = 1; i <= n; i++) {
if (!inDegree[i]) {
que.enQueue(i);
nodes[i]->times++;
}
}
while (!que.isEmpty()) {
current = que.deQueue();
for (p = nodes[current]->head; p; p = p->next) {
if (--inDegree[p->data] == 0) {
nodes[p->data]->times = nodes[current]->times + 1;
que.enQueue(p->data);
}
}
}
}
yyong119's solution
#include <cstdio>
#include <queue>
using namespace std;
int n, m, pr, ne, now, next, maxnum;
int indegree[10001];
queue<int> que[2], point[10001];
void topo(int depth, int state) {
if (que[state].empty()) {
maxnum = max(maxnum, depth - 1);
return;
}
while (que[state].size()) {
now = que[state].front(); que[state].pop();
while (point[now].size()) {
next = point[now].front();
indegree[next]--;
if (indegree[next] == 0) que[1 - state].push(next);
point[now].pop();
}
}
topo(depth + 1, 1 - state);
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d", &ne, &pr);
point[pr].push(ne);
indegree[ne]++;
}
for (int i = 1; i <= n; i++)
if (!indegree[i]&&point[i].size()) que[0].push(i);
maxnum = 1;
topo(1, 0);
printf("%d\n", maxnum);
return 0;
}