拓扑排序(c++)
·
拓扑排序:可以对有向图的数据按照先后顺序进行排序,也可以用来检测有向图中有没有环
题目
课程表
题目描述
你这个学期必须选修n门课程,记为0到n-1。在选修某些课程之前需要一些先修课程。给你一个数组p,其中p[i]=[ai,bi]表示如果想选修课程ai,则必须先选修课程bi。m表示数组p中数据个数
例如,想要学习课程0,你需要先完成课程1,我们用一个匹配来表示:[0,1]。
先输入n、m,再输入数组p。
请你判断是否可能完成所有课程的学习?如果可以,返回true;否则,返回false。
样例
输入:
2 2
1 0
0 1
输出
false
解释:课程1需要先学0,课程0又需要先学1,存在循环依赖,不可能完成。
代码
#include <bits/stdc++.h>
using namespace std;
int a[1010][1010];//邻接矩阵
int c[1010];//入度
int b[1010];//是否被访问
int r[1010];//排序结果
int lr;
int n,m;
queue<int> q;
void bfs();
int main()
{
cin>>n>>m;
for(int i = 0;i<m;i++)
{
int x,y;
cin>>x>>y;
a[y][x] = 1;//构建邻接矩阵
c[x]++;//增加入度的数量
}
bfs();
if(lr==n) cout<<"true";
else cout<<"false";
return 0;
}
void bfs()
{
for(int i = 0;i<n;i++)
{
if(c[i]==0)//入度等于0
{
q.push(i);
b[i] = 1;//标记已被访问
r[lr] = i;//排序
lr++;
}
}
while(q.empty()==false)
{
int head = q.front();
q.pop();
for(int i = 0;i<n;i++)
{
if(a[head][i]==1&&b[i]==0)
{
c[i]--;
if(c[i]==0)
{
q.push(i);
b[i] = 1;//标记已被访问
r[lr] = i;//排序
lr++;
}
}
}
}
}
课程表二
题目描述
现在你总共有n门课,编号为0到n-1。给你一个数组p,其中p[i=[ai,bi表示如果你想选修课程ai,则必须先完成课程bi。例如,[0,1]表示要选修课程0,必须先选修课程1。返回一种修完所有课程的顺序(可能存在多种有效顺序,你只需要返回其中一种)。如果不可能完成所有课程,返回一个空数组。m表示数组p中数据个数。
先输入n、m,再输入数组p。
样例
输入
4 4
1 0
2 0
3 1
3 2
输出
0 1 2 3
(0 2 1 3 也可以)
代码
#include <bits/stdc++.h>
using namespace std;
int a[1010][1010];//邻接矩阵
int c[1010];//入度
int b[1010];//是否被访问
int r[1010];//排序结果
int lr;
int n,m;
queue<int> q;
void bfs();
int main()
{
cin>>n>>m;
for(int i = 0;i<m;i++)
{
int x,y;
cin>>x>>y;
a[y][x] = 1;//构建邻接矩阵
c[x]++;//增加入度的数量
}
bfs();
if(lr==n)
{
for(int i = 0;i<lr;i++)
{
cout<<r[i]<<" ";
}
}
else
{
cout<<0;
}
return 0;
}
void bfs()
{
for(int i = 0;i<n;i++)
{
if(c[i]==0)//入度等于0
{
q.push(i);
b[i] = 1;//标记已被访问
r[lr] = i;//排序
lr++;
}
}
while(q.empty()==false)
{
int head = q.front();
q.pop();
for(int i = 0;i<n;i++)
{
if(a[head][i]==1&&b[i]==0)
{
c[i]--;
if(c[i]==0)
{
q.push(i);
b[i] = 1;//标记已被访问
r[lr] = i;//排序
lr++;
}
}
}
}
}
更多推荐



所有评论(0)