拓扑排序
拓扑排序
在一个有向无环图(DAG)中,我们将节点按照线性方式进行排序,使得对于任何的顶点u到v的有向边(u,v),都可以有u在v的前面。我们定义如果i到j有边,则认为j依赖于i,拓扑排序目标就是对节点进行排序,使得排在前面的节点不会依赖于后面的节点
Kahn算法:\(O(E+V)\)
int n, m;
queue<int> q;
map<pii, int> mp;
vector<int> g[N]; //邻接表存图
int du[N]; //入度
for (int i = 1; i <= n; ++i) //初始化
{
g[i].clear();
du[i] = 0;
}
for (int i = 1, u, v; i <= m; ++i)
{
cin >> u >> v;
if (!mp[make_pair(u, v)]) // 去除重边
{
g[u].push_back(v); //正向建边
du[u]++;
mp[make_pair(u, v)]++;
}
}
for (int i = 1; i <= n; ++i)
{
if (du[i] == 0) //找出入度为0的点加入队列
q.push(i);
}
int num = 0; // 用来判断是否有环
while (q.size())
{
int t = q.front();
num++;
q.pop();
for (int i = 0; i < g[t].size(); ++i)
{
du[g[t][i]]--; //去除所有连接到其他节点的边
if (du[g[t][i]] == 0)
{
q.push(g[t][i]);
}
}
}
if (num < n) //有环
cout << -1 << endl;